123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.Collections;
- using System.IO;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Cms
- {
- /**
- * general class for handling a pkcs7-signature message.
- *
- * A simple example of usage - note, in the example below the validity of
- * the certificate isn't verified, just the fact that one of the certs
- * matches the given signer...
- *
- * <pre>
- * IX509Store certs = s.GetCertificates();
- * SignerInformationStore signers = s.GetSignerInfos();
- *
- * foreach (SignerInformation signer in signers.GetSigners())
- * {
- * ArrayList certList = new ArrayList(certs.GetMatches(signer.SignerID));
- * X509Certificate cert = (X509Certificate) certList[0];
- *
- * if (signer.Verify(cert.GetPublicKey()))
- * {
- * verified++;
- * }
- * }
- * </pre>
- */
- public class CmsSignedData
- {
- private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance;
- private readonly CmsProcessable signedContent;
- private SignedData signedData;
- private ContentInfo contentInfo;
- private SignerInformationStore signerInfoStore;
- private IX509Store attrCertStore;
- private IX509Store certificateStore;
- private IX509Store crlStore;
- private IDictionary hashes;
- private CmsSignedData(
- CmsSignedData c)
- {
- this.signedData = c.signedData;
- this.contentInfo = c.contentInfo;
- this.signedContent = c.signedContent;
- this.signerInfoStore = c.signerInfoStore;
- }
- public CmsSignedData(
- byte[] sigBlock)
- : this(CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false)))
- {
- }
- public CmsSignedData(
- CmsProcessable signedContent,
- byte[] sigBlock)
- : this(signedContent, CmsUtilities.ReadContentInfo(new MemoryStream(sigBlock, false)))
- {
- }
- /**
- * 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))
- {
- }
- /**
- * 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))
- {
- }
- /**
- * base constructor - with encapsulated content
- */
- public CmsSignedData(
- Stream sigData)
- : this(CmsUtilities.ReadContentInfo(sigData))
- {
- }
- public CmsSignedData(
- CmsProcessable signedContent,
- ContentInfo sigData)
- {
- this.signedContent = signedContent;
- this.contentInfo = sigData;
- this.signedData = SignedData.GetInstance(contentInfo.Content);
- }
- public CmsSignedData(
- IDictionary hashes,
- ContentInfo sigData)
- {
- this.hashes = hashes;
- this.contentInfo = sigData;
- this.signedData = SignedData.GetInstance(contentInfo.Content);
- }
- public CmsSignedData(
- ContentInfo sigData)
- {
- this.contentInfo = sigData;
- this.signedData = SignedData.GetInstance(contentInfo.Content);
- //
- // this can happen if the signed message is sent simply to send a
- // certificate chain.
- //
- if (signedData.EncapContentInfo.Content != null)
- {
- this.signedContent = new CmsProcessableByteArray(
- ((Asn1OctetString)(signedData.EncapContentInfo.Content)).GetOctets());
- }
- // else
- // {
- // this.signedContent = null;
- // }
- }
- /// <summary>Return the version number for this object.</summary>
- public int Version
- {
- get { return signedData.Version.IntValueExact; }
- }
- internal IX509Store GetCertificates()
- {
- return Helper.GetCertificates(signedData.Certificates);
- }
- /**
- * return the collection of signers that are associated with the
- * signatures for the message.
- */
- public SignerInformationStore GetSignerInfos()
- {
- if (signerInfoStore == null)
- {
- IList signerInfos = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
- Asn1Set s = signedData.SignerInfos;
- foreach (object obj in s)
- {
- SignerInfo info = SignerInfo.GetInstance(obj);
- DerObjectIdentifier contentType = signedData.EncapContentInfo.ContentType;
- if (hashes == null)
- {
- signerInfos.Add(new SignerInformation(info, contentType, signedContent, null));
- }
- else
- {
- byte[] hash = (byte[])hashes[info.DigestAlgorithm.Algorithm.Id];
- signerInfos.Add(new SignerInformation(info, contentType, null, new BaseDigestCalculator(hash)));
- }
- }
- signerInfoStore = new SignerInformationStore(signerInfos);
- }
- return signerInfoStore;
- }
- /**
- * return a X509Store containing the attribute certificates, if any, contained
- * in this message.
- *
- * @param type type of store to create
- * @return a store of attribute certificates
- * @exception NoSuchStoreException if the store type isn't available.
- * @exception CmsException if a general exception prevents creation of the X509Store
- */
- public IX509Store GetAttributeCertificates(
- string type)
- {
- if (attrCertStore == null)
- {
- attrCertStore = Helper.CreateAttributeStore(type, signedData.Certificates);
- }
- return attrCertStore;
- }
- /**
- * return a X509Store containing the public key certificates, if any, contained
- * in this message.
- *
- * @param type type of store to create
- * @return a store of public key certificates
- * @exception NoSuchStoreException if the store type isn't available.
- * @exception CmsException if a general exception prevents creation of the X509Store
- */
- public IX509Store GetCertificates(
- string type)
- {
- if (certificateStore == null)
- {
- certificateStore = Helper.CreateCertificateStore(type, signedData.Certificates);
- }
- return certificateStore;
- }
- /**
- * return a X509Store containing CRLs, if any, contained
- * in this message.
- *
- * @param type type of store to create
- * @return a store of CRLs
- * @exception NoSuchStoreException if the store type isn't available.
- * @exception CmsException if a general exception prevents creation of the X509Store
- */
- public IX509Store GetCrls(
- string type)
- {
- if (crlStore == null)
- {
- crlStore = Helper.CreateCrlStore(type, signedData.CRLs);
- }
- return crlStore;
- }
- public string SignedContentTypeOid
- {
- get { return signedData.EncapContentInfo.ContentType.Id; }
- }
- /// <summary>
- /// Return the <c>DerObjectIdentifier</c> associated with the encapsulated
- /// content info structure carried in the signed data.
- /// </summary>
- public DerObjectIdentifier SignedContentType
- {
- get { return signedData.EncapContentInfo.ContentType; }
- }
- public CmsProcessable SignedContent
- {
- get { return signedContent; }
- }
- /**
- * return the ContentInfo
- */
- public ContentInfo ContentInfo
- {
- get { return contentInfo; }
- }
- /**
- * return the ASN.1 encoded representation of this object.
- */
- public byte[] GetEncoded()
- {
- return contentInfo.GetEncoded();
- }
- /**
- * return the ASN.1 encoded representation of this object using the specified encoding.
- *
- * @param encoding the ASN.1 encoding format to use ("BER" or "DER").
- */
- public byte[] GetEncoded(string encoding)
- {
- return contentInfo.GetEncoded(encoding);
- }
- /**
- * Replace the signerinformation store associated with this
- * CmsSignedData object with the new one passed in. You would
- * probably only want to do this if you wanted to change the unsigned
- * attributes associated with a signer, or perhaps delete one.
- *
- * @param signedData the signed data object to be used as a base.
- * @param signerInformationStore the new signer information store to use.
- * @return a new signed data object.
- */
- public static CmsSignedData ReplaceSigners(
- CmsSignedData signedData,
- SignerInformationStore signerInformationStore)
- {
- //
- // copy
- //
- CmsSignedData cms = new CmsSignedData(signedData);
- //
- // replace the store
- //
- cms.signerInfoStore = signerInformationStore;
- //
- // replace the signers in the SignedData object
- //
- Asn1EncodableVector digestAlgs = new Asn1EncodableVector();
- Asn1EncodableVector vec = new Asn1EncodableVector();
- foreach (SignerInformation signer in signerInformationStore.GetSigners())
- {
- digestAlgs.Add(Helper.FixAlgID(signer.DigestAlgorithmID));
- vec.Add(signer.ToSignerInfo());
- }
- Asn1Set digests = new DerSet(digestAlgs);
- Asn1Set signers = new DerSet(vec);
- Asn1Sequence sD = (Asn1Sequence)signedData.signedData.ToAsn1Object();
- //
- // signers are the last item in the sequence.
- //
- vec = new Asn1EncodableVector(
- sD[0], // version
- digests);
- for (int i = 2; i != sD.Count - 1; i++)
- {
- vec.Add(sD[i]);
- }
- vec.Add(signers);
- cms.signedData = SignedData.GetInstance(new BerSequence(vec));
- //
- // replace the contentInfo with the new one
- //
- cms.contentInfo = new ContentInfo(cms.contentInfo.ContentType, cms.signedData);
- return cms;
- }
- /**
- * 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 BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.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;
- }
- }
- }
- #pragma warning restore
- #endif
|