/** * generate a signed object that for a CMS Signed Data * object using the given provider - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. * @param out stream the CMS object is to be written to. * @param signedContentType OID for data to be signed. * @param encapsulate true if data should be encapsulated. * @param dataOutputStream output stream to copy the data being signed to. */ public Stream Open( Stream outStream, string signedContentType, bool encapsulate, Stream dataOutputStream) { if (outStream == null) { throw new ArgumentNullException("outStream"); } if (!outStream.CanWrite) { throw new ArgumentException("Expected writeable stream", "outStream"); } if (dataOutputStream != null && !dataOutputStream.CanWrite) { throw new ArgumentException("Expected writeable stream", "dataOutputStream"); } _messageDigestsLocked = true; // // ContentInfo // BerSequenceGenerator sGen = new BerSequenceGenerator(outStream); sGen.AddObject(CmsObjectIdentifiers.SignedData); // // Signed Data // BerSequenceGenerator sigGen = new BerSequenceGenerator( sGen.GetRawOutputStream(), 0, true); sigGen.AddObject(CalculateVersion(signedContentType)); Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); foreach (string digestOid in _messageDigestOids) { digestAlgs.Add( new AlgorithmIdentifier(new DerObjectIdentifier(digestOid), DerNull.Instance)); } { byte[] tmp = new DerSet(digestAlgs).GetEncoded(); sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length); } BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream()); eiGen.AddObject(new DerObjectIdentifier(signedContentType)); Stream digStream; if (encapsulate) { BerOctetStringGenerator octGen = new BerOctetStringGenerator( eiGen.GetRawOutputStream(), 0, true); digStream = octGen.GetOctetOutputStream(_bufferSize); if (dataOutputStream != null) { digStream = new TeeOutputStream(dataOutputStream, digStream); } } else { if (dataOutputStream != null) { digStream = dataOutputStream; } else { digStream = new NullOutputStream(); } } foreach (IDigest d in _messageDigests.Values) { digStream = new DigestStream(digStream, null, d); } return(new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen)); }
/** * generate a signed object that for a CMS Signed Data * object - if encapsulate is true a copy * of the message will be included in the signature. The content type * is set according to the OID represented by the string signedContentType. */ public Stream Open( Stream outStream, string signedContentType, bool encapsulate) { // // ContentInfo // BerSequenceGenerator sGen = new BerSequenceGenerator(outStream); sGen.AddObject(CmsObjectIdentifiers.SignedData); // // Signed Data // BerSequenceGenerator sigGen = new BerSequenceGenerator( sGen.GetRawOutputStream(), 0, true); sigGen.AddObject(CalculateVersion(signedContentType)); Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); // // add the precalculated SignerInfo digest algorithms. // foreach (SignerInformation signer in _signers) { digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID)); } // // add the new digests // foreach (SignerInf signer in _signerInfs) { digestAlgs.Add(FixAlgID(signer.DigestAlgorithmID)); } { byte[] tmp = new DerSet(digestAlgs).GetEncoded(); sigGen.GetRawOutputStream().Write(tmp, 0, tmp.Length); } BerSequenceGenerator eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream()); eiGen.AddObject(new DerObjectIdentifier(signedContentType)); Stream digStream; if (encapsulate) { BerOctetStringGenerator octGen = new BerOctetStringGenerator( eiGen.GetRawOutputStream(), 0, true); if (_bufferSize != 0) { digStream = octGen.GetOctetOutputStream(new byte[_bufferSize]); } else { digStream = octGen.GetOctetOutputStream(); } } else { digStream = new NullOutputStream(); } foreach (IDigest d in _messageDigests) { digStream = new DigestStream(digStream, null, d); } return(new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen)); }