private void DoClose() { Platform.Dispose(_out); // 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 // Asn1EncodableVector signerInfos = new Asn1EncodableVector(); // // add the generated SignerInfo objects // { foreach (DigestAndSignerInfoGeneratorHolder holder in outer._signerInfs) { AlgorithmIdentifier digestAlgorithm = holder.DigestAlgorithm; byte[] 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(); }
/** * 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); }
/** * 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 CmsSignedData Generate( string signedContentType, // FIXME Avoid accessing more than once to support CmsProcessableInputStream CmsProcessable content, bool encapsulate) { Asn1EncodableVector digestAlgs = new Asn1EncodableVector(); Asn1EncodableVector signerInfos = new Asn1EncodableVector(); _digests.Clear(); // clear the current preserved digest state // // add the precalculated SignerInfo objects. // foreach (SignerInformation signer in _signers) { digestAlgs.Add(Helper.FixAlgID(signer.DigestAlgorithmID)); // TODO Verify the content type and calculated digest match the precalculated SignerInfo signerInfos.Add(signer.ToSignerInfo()); } // // add the SignerInfo objects // bool isCounterSignature = (signedContentType == null); DerObjectIdentifier contentTypeOid = isCounterSignature ? null : new DerObjectIdentifier(signedContentType); foreach (SignerInf signer in signerInfs) { try { digestAlgs.Add(signer.DigestAlgorithmID); signerInfos.Add(signer.ToSignerInfo(contentTypeOid, content, rand)); } catch (IOException e) { throw new CmsException("encoding error.", e); } catch (InvalidKeyException e) { throw new CmsException("key inappropriate for signature.", e); } catch (SignatureException e) { throw new CmsException("error creating signature.", e); } catch (CertificateEncodingException e) { throw new CmsException("error creating sid.", e); } } Asn1Set certificates = null; if (_certs.Count != 0) { certificates = CmsUtilities.CreateBerSetFromList(_certs); } Asn1Set certrevlist = null; if (_crls.Count != 0) { certrevlist = CmsUtilities.CreateBerSetFromList(_crls); } Asn1OctetString octs = null; if (encapsulate) { MemoryStream bOut = new MemoryStream(); if (content != null) { try { content.Write(bOut); } catch (IOException e) { throw new CmsException("encapsulation error.", e); } } octs = new BerOctetString(bOut.ToArray()); } ContentInfo encInfo = new ContentInfo(contentTypeOid, octs); SignedData sd = new SignedData( new DerSet(digestAlgs), encInfo, certificates, certrevlist, new DerSet(signerInfos)); ContentInfo contentInfo = new ContentInfo(CmsObjectIdentifiers.SignedData, sd); return(new CmsSignedData(content, contentInfo)); }