/** * 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 // var sGen = new BerSequenceGenerator(outStream); sGen.AddObject(CmsObjectIdentifiers.SignedData); // // Signed Data // var sigGen = new BerSequenceGenerator(sGen.GetRawOutputStream(), 0, true); bool isCounterSignature = (signedContentType == null); DerObjectIdentifier contentTypeOid = isCounterSignature ? null : new DerObjectIdentifier(signedContentType); sigGen.AddObject(CalculateVersion(contentTypeOid)); var 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); } var eiGen = new BerSequenceGenerator(sigGen.GetRawOutputStream()); eiGen.AddObject(contentTypeOid); // If encapsulating, add the data as an octet string in the sequence Stream encapStream = encapsulate ? CmsUtilities.CreateBerOctetOutputStream(eiGen.GetRawOutputStream(), 0, true, _bufferSize) : null; // Also send the data to 'dataOutputStream' if necessary Stream teeStream = GetSafeTeeOutputStream(dataOutputStream, encapStream); // Let all the digests see the data as it is written Stream digStream = AttachDigestsToOutputStream(_messageDigests.Values, teeStream); return(new CmsSignedDataOutputStream(this, digStream, signedContentType, sGen, sigGen, eiGen)); }
protected override void Dispose(bool disposing) { try { if (!disposing) { return; } _out.Dispose(); // TODO Parent context(s) should really be be closed explicitly _eiGen.Close(); _outer._digests.Clear(); // clear the current preserved digest state if (_outer._certs.Count > 0) { Asn1Set certs = CmsUtilities.CreateBerSetFromList(_outer._certs); WriteToGenerator(_sigGen, new BerTaggedObject(false, 0, certs)); } if (_outer._crls.Count > 0) { Asn1Set crls = CmsUtilities.CreateBerSetFromList(_outer._crls); WriteToGenerator(_sigGen, new BerTaggedObject(false, 1, crls)); } // // Calculate the digest hashes // foreach (DictionaryEntry de in _outer._messageDigests) { _outer._messageHashes.Add(de.Key, DigestUtilities.DoFinal((IDigest)de.Value)); } // TODO If the digest OIDs for precalculated signers weren't mixed in with // the others, we could fill in outer._digests here, instead of SignerInfoGenerator.Generate // // collect all the SignerInfo objects // var signerInfos = new Asn1EncodableVector(); // // add the generated SignerInfo objects // { foreach (DigestAndSignerInfoGeneratorHolder holder in _outer._signerInfs) { AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm; var calculatedDigest = (byte[])_outer._messageHashes[Helper.GetDigestAlgName(holder.DigestOID)]; _outer._digests[holder.DigestOID] = calculatedDigest.Clone(); signerInfos.Add(holder.SignerInf.Generate(_contentOID, digestAlgorithm, calculatedDigest)); } } // // add the precalculated SignerInfo objects. // { foreach (SignerInformation signer in _outer._signers) { // TODO Verify the content type and calculated digest match the precalculated SignerInfo // if (!signer.ContentType.Equals(_contentOID)) // { // // TODO The precalculated content type did not match - error? // } // // byte[] calculatedDigest = (byte[])outer._digests[signer.DigestAlgOid]; // if (calculatedDigest == null) // { // // TODO We can't confirm this digest because we didn't calculate it - error? // } // else // { // if (!Arrays.AreEqual(signer.GetContentDigest(), calculatedDigest)) // { // // TODO The precalculated digest did not match - error? // } // } signerInfos.Add(signer.ToSignerInfo()); } } WriteToGenerator(_sigGen, new DerSet(signerInfos)); _sigGen.Close(); _sGen.Close(); } finally { base.Dispose(disposing); } }
/** * base constructor - content with detached signature. * * @param signedContent the content that was signed. * @param sigData the signature object. */ public CmsSignedData( CmsProcessable signedContent, Stream sigData) : this(signedContent, CmsUtilities.ReadContentInfo(sigData)) { }
private Stream Open( Stream outStream, AlgorithmIdentifier encAlgID, ICipherParameters cipherParameters, Asn1EncodableVector recipientInfos) { try { // // ContentInfo // BerSequenceGenerator cGen = new BerSequenceGenerator(outStream); cGen.AddObject(CmsObjectIdentifiers.EnvelopedData); // // Encrypted Data // BerSequenceGenerator envGen = new BerSequenceGenerator( cGen.GetRawOutputStream(), 0, true); envGen.AddObject(this.Version); Stream envRaw = envGen.GetRawOutputStream(); Asn1Generator recipGen = _berEncodeRecipientSet ? (Asn1Generator) new BerSetGenerator(envRaw) : new DerSetGenerator(envRaw); foreach (Asn1Encodable ae in recipientInfos) { recipGen.AddObject(ae); } recipGen.Close(); BerSequenceGenerator eiGen = new BerSequenceGenerator(envRaw); eiGen.AddObject(CmsObjectIdentifiers.Data); eiGen.AddObject(encAlgID); Stream octetOutputStream = CmsUtilities.CreateBerOctetOutputStream( eiGen.GetRawOutputStream(), 0, false, _bufferSize); IBufferedCipher cipher = CipherUtilities.GetCipher(encAlgID.ObjectID); cipher.Init(true, new ParametersWithRandom(cipherParameters, rand)); CipherStream cOut = new CipherStream(octetOutputStream, null, cipher); return(new CmsEnvelopedDataOutputStream(this, cOut, cGen, envGen, eiGen)); } catch (SecurityUtilityException e) { throw new CmsException("couldn't create cipher.", e); } catch (InvalidKeyException e) { throw new CmsException("key invalid in message.", e); } catch (IOException e) { throw new CmsException("exception decoding algorithm parameters.", e); } }
/** * Content with detached signature, digests precomputed * * @param hashes a map of precomputed digests for content indexed by name of hash. * @param sigBlock the signature object. */ public CmsSignedData( IDictionary hashes, byte[] sigBlock) : this(hashes, CmsUtilities.ReadContentInfo(sigBlock)) { }
public CmsSignedData( CmsProcessable signedContent, byte[] sigBlock) : this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false))) { }
public CmsSignedData( byte[] sigBlock) : this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false))) { }
/** * Replace the certificate and CRL information associated with this * CmsSignedData object with the new one passed in. * * @param signedData the signed data object to be used as a base. * @param x509Certs the new certificates to be used. * @param x509Crls the new CRLs to be used. * @return a new signed data object. * @exception CmsException if there is an error processing the stores */ public static CmsSignedData ReplaceCertificatesAndCrls( CmsSignedData signedData, IX509Store x509Certs, IX509Store x509Crls, IX509Store x509AttrCerts) { if (x509AttrCerts != null) { throw Platform.CreateNotImplementedException("Currently can't replace attribute certificates"); } // // copy // CmsSignedData cms = new CmsSignedData(signedData); // // replace the certs and crls in the SignedData object // Asn1Set certs = null; try { Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList( CmsUtilities.GetCertificatesFromStore(x509Certs)); if (asn1Set.Count != 0) { certs = asn1Set; } } catch (X509StoreException e) { throw new CmsException("error getting certificates from store", e); } Asn1Set crls = null; try { Asn1Set asn1Set = CmsUtilities.CreateBerSetFromList( CmsUtilities.GetCrlsFromStore(x509Crls)); if (asn1Set.Count != 0) { crls = asn1Set; } } catch (X509StoreException e) { throw new CmsException("error getting CRLs from store", e); } // // replace the CMS structure. // SignedData old = signedData.signedData; cms.signedData = new SignedData( old.DigestAlgorithms, old.EncapContentInfo, certs, crls, old.SignerInfos); // // replace the contentInfo with the new one // cms.contentInfo = new ContentInfo(cms.contentInfo.ContentType, cms.signedData); return(cms); }
/** * base constructor - with encapsulated content */ public CmsSignedData( Stream sigData) : this(CmsUtilities.ReadContentInfo(sigData)) { }