/**
* Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes
* in the signerInfo can also be set, OR a time-stamp-authority client
* may be provided.
* @param secondDigest the digest in the authenticatedAttributes
* @param signingTime the signing time in the authenticatedAttributes
* @param tsaClient TSAClient - null or an optional time stamp authority client
* @return byte[] the bytes for the PKCS7SignedData object
* @since 2.1.6
*/
public byte[] GetEncodedPKCS7(byte[] secondDigest, DateTime signingTime, ITSAClient tsaClient, byte[] ocsp, ICollection <byte[]> crlBytes, CryptoStandard sigtype)
{
if (externalDigest != null)
{
digest = externalDigest;
if (RSAdata != null)
{
RSAdata = externalRSAdata;
}
}
else if (externalRSAdata != null && RSAdata != null)
{
RSAdata = externalRSAdata;
sig.BlockUpdate(RSAdata, 0, RSAdata.Length);
digest = sig.GenerateSignature();
}
else
{
if (RSAdata != null)
{
RSAdata = new byte[messageDigest.GetDigestSize()];
messageDigest.DoFinal(RSAdata, 0);
sig.BlockUpdate(RSAdata, 0, RSAdata.Length);
}
digest = sig.GenerateSignature();
}
// Create the set of Hash algorithms
Asn1EncodableVector digestAlgorithms = new Asn1EncodableVector();
foreach (string dal in digestalgos.Keys)
{
Asn1EncodableVector algos = new Asn1EncodableVector();
algos.Add(new DerObjectIdentifier(dal));
algos.Add(DerNull.Instance);
digestAlgorithms.Add(new DerSequence(algos));
}
// Create the contentInfo.
Asn1EncodableVector v = new Asn1EncodableVector();
v.Add(new DerObjectIdentifier(SecurityIDs.ID_PKCS7_DATA));
if (RSAdata != null)
{
v.Add(new DerTaggedObject(0, new DerOctetString(RSAdata)));
}
DerSequence contentinfo = new DerSequence(v);
// Get all the certificates
//
v = new Asn1EncodableVector();
foreach (X509Certificate xcert in certs)
{
Asn1InputStream tempstream = new Asn1InputStream(new MemoryStream(xcert.GetEncoded()));
v.Add(tempstream.ReadObject());
}
DerSet dercertificates = new DerSet(v);
// Create signerinfo structure.
//
Asn1EncodableVector signerinfo = new Asn1EncodableVector();
// Add the signerInfo version
//
signerinfo.Add(new DerInteger(signerversion));
v = new Asn1EncodableVector();
v.Add(CertificateInfo.GetIssuer(signCert.GetTbsCertificate()));
v.Add(new DerInteger(signCert.SerialNumber));
signerinfo.Add(new DerSequence(v));
// Add the digestAlgorithm
v = new Asn1EncodableVector();
v.Add(new DerObjectIdentifier(digestAlgorithmOid));
v.Add(DerNull.Instance);
signerinfo.Add(new DerSequence(v));
// add the authenticated attribute if present
if (secondDigest != null /*&& signingTime != null*/)
{
signerinfo.Add(new DerTaggedObject(false, 0, GetAuthenticatedAttributeSet(secondDigest, signingTime, ocsp, crlBytes, sigtype)));
}
// Add the digestEncryptionAlgorithm
v = new Asn1EncodableVector();
v.Add(new DerObjectIdentifier(digestEncryptionAlgorithmOid));
v.Add(DerNull.Instance);
signerinfo.Add(new DerSequence(v));
// Add the digest
signerinfo.Add(new DerOctetString(digest));
// When requested, go get and add the timestamp. May throw an exception.
// Added by Martin Brunecky, 07/12/2007 folowing Aiken Sam, 2006-11-15
// Sam found Adobe expects time-stamped SHA1-1 of the encrypted digest
if (tsaClient != null)
{
byte[] tsImprint = DigestAlgorithms.Digest(tsaClient.GetMessageDigest(), digest);
byte[] tsToken = tsaClient.GetTimeStampToken(tsImprint);
if (tsToken != null)
{
Asn1EncodableVector unauthAttributes = BuildUnauthenticatedAttributes(tsToken);
if (unauthAttributes != null)
{
signerinfo.Add(new DerTaggedObject(false, 1, new DerSet(unauthAttributes)));
}
}
}
// Finally build the body out of all the components above
Asn1EncodableVector body = new Asn1EncodableVector();
body.Add(new DerInteger(version));
body.Add(new DerSet(digestAlgorithms));
body.Add(contentinfo);
body.Add(new DerTaggedObject(false, 0, dercertificates));
// Only allow one signerInfo
body.Add(new DerSet(new DerSequence(signerinfo)));
// Now we have the body, wrap it in it's PKCS7Signed shell
// and return it
//
Asn1EncodableVector whole = new Asn1EncodableVector();
whole.Add(new DerObjectIdentifier(SecurityIDs.ID_PKCS7_SIGNED_DATA));
whole.Add(new DerTaggedObject(0, new DerSequence(body)));
MemoryStream bOut = new MemoryStream();
Asn1OutputStream dout = new Asn1OutputStream(bOut);
dout.WriteObject(new DerSequence(whole));
dout.Close();
return(bOut.ToArray());
}