diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-11-06 17:43:41 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-11-06 17:43:41 +0700 |
commit | c1d0de54d5ae25ea78cde7ff30e58a5fd07e089c (patch) | |
tree | f2d77abd46e1004d7f0d765bd619e49501c1024c /crypto/src/cms | |
parent | Asn1 GetInstance refactoring (diff) | |
download | BouncyCastle.NET-ed25519-c1d0de54d5ae25ea78cde7ff30e58a5fd07e089c.tar.xz |
CMS support for OtherRevocationInfoFormat
- see https://github.com/bcgit/bc-csharp/pull/328
Diffstat (limited to 'crypto/src/cms')
-rw-r--r-- | crypto/src/cms/CMSSignedData.cs | 62 | ||||
-rw-r--r-- | crypto/src/cms/CMSSignedDataParser.cs | 9 | ||||
-rw-r--r-- | crypto/src/cms/CMSSignedGenerator.cs | 17 | ||||
-rw-r--r-- | crypto/src/cms/CMSSignedHelper.cs | 26 | ||||
-rw-r--r-- | crypto/src/cms/CMSUtils.cs | 52 | ||||
-rw-r--r-- | crypto/src/cms/OriginatorInfoGenerator.cs | 59 |
6 files changed, 189 insertions, 36 deletions
diff --git a/crypto/src/cms/CMSSignedData.cs b/crypto/src/cms/CMSSignedData.cs index 3d4ce05a6..773e15be0 100644 --- a/crypto/src/cms/CMSSignedData.cs +++ b/crypto/src/cms/CMSSignedData.cs @@ -204,6 +204,11 @@ namespace Org.BouncyCastle.Cms return Helper.GetCrls(signedData.CRLs); } + public IStore<Asn1Encodable> GetOtherRevInfos(DerObjectIdentifier otherRevInfoFormat) + { + return Helper.GetOtherRevInfos(signedData.CRLs, otherRevInfoFormat); + } + /// <summary> /// Return the <c>DerObjectIdentifier</c> associated with the encapsulated /// content info structure carried in the signed data. @@ -308,7 +313,7 @@ namespace Org.BouncyCastle.Cms return cms; } - /** + /** * Replace the certificate and CRL information associated with this * CmsSignedData object with the new one passed in. * @@ -318,48 +323,69 @@ namespace Org.BouncyCastle.Cms * @return a new signed data object. * @exception CmsException if there is an error processing the stores */ - public static CmsSignedData ReplaceCertificatesAndCrls(CmsSignedData signedData, IStore<X509Certificate> x509Certs, - IStore<X509Crl> x509Crls, IStore<X509V2AttributeCertificate> x509AttrCerts) + public static CmsSignedData ReplaceCertificatesAndCrls(CmsSignedData signedData, + IStore<X509Certificate> x509Certs, IStore<X509Crl> x509Crls) { - // - // copy - // - CmsSignedData cms = new CmsSignedData(signedData); + return ReplaceCertificatesAndRevocations(signedData, x509Certs, x509Crls, null, null); + } + + public static CmsSignedData ReplaceCertificatesAndCrls(CmsSignedData signedData, + IStore<X509Certificate> x509Certs, IStore<X509Crl> x509Crls, + IStore<X509V2AttributeCertificate> x509AttrCerts) + { + return ReplaceCertificatesAndRevocations(signedData, x509Certs, x509Crls, x509AttrCerts, null); + } + + public static CmsSignedData ReplaceCertificatesAndRevocations(CmsSignedData signedData, + IStore<X509Certificate> x509Certs, IStore<X509Crl> x509Crls, + IStore<X509V2AttributeCertificate> x509AttrCerts, IStore<OtherRevocationInfoFormat> otherRevocationInfos) + { + // + // copy + // + CmsSignedData cms = new CmsSignedData(signedData); // // replace the certs and crls in the SignedData object // Asn1Set certSet = null; - Asn1Set crlSet = null; + Asn1Set revocationSet = null; if (x509Certs != null || x509AttrCerts != null) { - var certs = new List<Asn1Encodable>(); - + var certificates = new List<Asn1Encodable>(); if (x509Certs != null) { - certs.AddRange(CmsUtilities.GetCertificatesFromStore(x509Certs)); + certificates.AddRange(CmsUtilities.GetCertificatesFromStore(x509Certs)); } if (x509AttrCerts != null) { - certs.AddRange(CmsUtilities.GetAttributeCertificatesFromStore(x509AttrCerts)); + certificates.AddRange(CmsUtilities.GetAttributeCertificatesFromStore(x509AttrCerts)); } - Asn1Set berSet = CmsUtilities.CreateBerSetFromList(certs); + Asn1Set berSet = CmsUtilities.CreateBerSetFromList(certificates); if (berSet.Count > 0) { certSet = berSet; } } - if (x509Crls != null) + if (x509Crls != null || otherRevocationInfos != null) { - var crls = CmsUtilities.GetCrlsFromStore(x509Crls); + var revocations = new List<Asn1Encodable>(); + if (x509Crls != null) + { + revocations.AddRange(CmsUtilities.GetCrlsFromStore(x509Crls)); + } + if (otherRevocationInfos != null) + { + revocations.AddRange(CmsUtilities.GetOtherRevocationInfosFromStore(otherRevocationInfos)); + } - Asn1Set berSet = CmsUtilities.CreateBerSetFromList(crls); + Asn1Set berSet = CmsUtilities.CreateBerSetFromList(revocations); if (berSet.Count > 0) { - crlSet = berSet; + revocationSet = berSet; } } @@ -371,7 +397,7 @@ namespace Org.BouncyCastle.Cms old.DigestAlgorithms, old.EncapContentInfo, certSet, - crlSet, + revocationSet, old.SignerInfos); // diff --git a/crypto/src/cms/CMSSignedDataParser.cs b/crypto/src/cms/CMSSignedDataParser.cs index 78e29e6a3..c5dc795a8 100644 --- a/crypto/src/cms/CMSSignedDataParser.cs +++ b/crypto/src/cms/CMSSignedDataParser.cs @@ -275,7 +275,14 @@ namespace Org.BouncyCastle.Cms return Helper.GetCrls(_crlSet); } - private void PopulateCertCrlSets() + public IStore<Asn1Encodable> GetOtherRevInfos(DerObjectIdentifier otherRevInfoFormat) + { + PopulateCertCrlSets(); + + return Helper.GetOtherRevInfos(_crlSet, otherRevInfoFormat); + } + + private void PopulateCertCrlSets() { if (_isCertCrlParsed) return; diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs index 24af9b56a..fd40de469 100644 --- a/crypto/src/cms/CMSSignedGenerator.cs +++ b/crypto/src/cms/CMSSignedGenerator.cs @@ -588,6 +588,23 @@ namespace Org.BouncyCastle.Cms _crls.AddRange(CmsUtilities.GetCrlsFromStore(crlStore)); } + public void AddOtherRevocationInfo(OtherRevocationInfoFormat otherRevocationInfo) + { + CmsUtilities.ValidateOtherRevocationInfo(otherRevocationInfo); + _crls.Add(new DerTaggedObject(false, 1, otherRevocationInfo)); + } + + public void AddOtherRevocationInfos(IStore<OtherRevocationInfoFormat> otherRevocationInfoStore) + { + _crls.AddRange(CmsUtilities.GetOtherRevocationInfosFromStore(otherRevocationInfoStore)); + } + + public void AddOtherRevocationInfos(DerObjectIdentifier otherRevInfoFormat, + IStore<Asn1Encodable> otherRevInfoStore) + { + _crls.AddRange(CmsUtilities.GetOtherRevocationInfosFromStore(otherRevInfoStore, otherRevInfoFormat)); + } + /** * Add a store of precalculated signers to the generator. * diff --git a/crypto/src/cms/CMSSignedHelper.cs b/crypto/src/cms/CMSSignedHelper.cs index 79290846e..9db39549b 100644 --- a/crypto/src/cms/CMSSignedHelper.cs +++ b/crypto/src/cms/CMSSignedHelper.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.Cms; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.Eac; +using Org.BouncyCastle.Asn1.Esf; using Org.BouncyCastle.Asn1.Nist; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; @@ -348,5 +350,29 @@ namespace Org.BouncyCastle.Cms } return CollectionUtilities.CreateStore(contents); } + + internal IStore<Asn1Encodable> GetOtherRevInfos(Asn1Set crlSet, DerObjectIdentifier otherRevInfoFormat) + { + var contents = new List<Asn1Encodable>(); + if (crlSet != null && otherRevInfoFormat != null) + { + foreach (Asn1Encodable ae in crlSet) + { + if (ae != null && ae.ToAsn1Object() is Asn1TaggedObject taggedObject) + { + if (taggedObject.HasContextTag(1)) + { + var otherRevocationInfo = OtherRevocationInfoFormat.GetInstance(taggedObject, false); + + if (otherRevInfoFormat.Equals(otherRevocationInfo.InfoFormat)) + { + contents.Add(otherRevocationInfo.Info); + } + } + } + } + } + return CollectionUtilities.CreateStore(contents); + } } } diff --git a/crypto/src/cms/CMSUtils.cs b/crypto/src/cms/CMSUtils.cs index 6800c1d2a..1a1577c4e 100644 --- a/crypto/src/cms/CMSUtils.cs +++ b/crypto/src/cms/CMSUtils.cs @@ -4,6 +4,7 @@ using System.IO; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; +using Org.BouncyCastle.Asn1.Ocsp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.Utilities.IO; @@ -112,12 +113,46 @@ namespace Org.BouncyCastle.Cms foreach (var crl in crlStore.EnumerateMatches(null)) { result.Add(crl.CertificateList); - } + } } return result; } - internal static Asn1Set CreateBerSetFromList(IEnumerable<Asn1Encodable> elements) + internal static List<Asn1TaggedObject> GetOtherRevocationInfosFromStore( + IStore<OtherRevocationInfoFormat> otherRevocationInfoStore) + { + var result = new List<Asn1TaggedObject>(); + if (otherRevocationInfoStore != null) + { + foreach (var otherRevocationInfo in otherRevocationInfoStore.EnumerateMatches(null)) + { + ValidateOtherRevocationInfo(otherRevocationInfo); + + result.Add(new DerTaggedObject(false, 1, otherRevocationInfo)); + } + } + return result; + } + + internal static List<DerTaggedObject> GetOtherRevocationInfosFromStore(IStore<Asn1Encodable> otherRevInfoStore, + DerObjectIdentifier otherRevInfoFormat) + { + var result = new List<DerTaggedObject>(); + if (otherRevInfoStore != null && otherRevInfoFormat != null) + { + foreach (var otherRevInfo in otherRevInfoStore.EnumerateMatches(null)) + { + var otherRevocationInfo = new OtherRevocationInfoFormat(otherRevInfoFormat, otherRevInfo); + + ValidateOtherRevocationInfo(otherRevocationInfo); + + result.Add(new DerTaggedObject(false, 1, otherRevocationInfo)); + } + } + return result; + } + + internal static Asn1Set CreateBerSetFromList(IEnumerable<Asn1Encodable> elements) { Asn1EncodableVector v = new Asn1EncodableVector(); @@ -157,5 +192,16 @@ namespace Org.BouncyCastle.Cms TbsCertificateStructure tbsCert = GetTbsCertificateStructure(cert); return new IssuerAndSerialNumber(tbsCert.Issuer, tbsCert.SerialNumber.Value); } - } + + internal static void ValidateOtherRevocationInfo(OtherRevocationInfoFormat otherRevocationInfo) + { + if (CmsObjectIdentifiers.id_ri_ocsp_response.Equals(otherRevocationInfo.InfoFormat)) + { + OcspResponse ocspResponse = OcspResponse.GetInstance(otherRevocationInfo.Info); + + if (OcspResponseStatus.Successful != ocspResponse.ResponseStatus.IntValueExact) + throw new ArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); + } + } + } } diff --git a/crypto/src/cms/OriginatorInfoGenerator.cs b/crypto/src/cms/OriginatorInfoGenerator.cs index d7d24dcc4..ec6d2d8d8 100644 --- a/crypto/src/cms/OriginatorInfoGenerator.cs +++ b/crypto/src/cms/OriginatorInfoGenerator.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cms; -using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.X509; @@ -11,30 +9,63 @@ namespace Org.BouncyCastle.Cms { public class OriginatorInfoGenerator { - private readonly List<X509CertificateStructure> origCerts; - private readonly List<CertificateList> origCrls; + private readonly List<Asn1Encodable> origCerts; + private readonly List<Asn1Encodable> origCrls; public OriginatorInfoGenerator(X509Certificate origCert) { - this.origCerts = new List<X509CertificateStructure>(); + this.origCerts = new List<Asn1Encodable>{ origCert.CertificateStructure }; this.origCrls = null; - origCerts.Add(origCert.CertificateStructure); } - public OriginatorInfoGenerator(IStore<X509Certificate> origCerts) - : this(origCerts, null) + public OriginatorInfoGenerator(IStore<X509Certificate> x509Certs) + : this(x509Certs, null, null, null) { } - public OriginatorInfoGenerator(IStore<X509Certificate> origCerts, IStore<X509Crl> origCrls) + public OriginatorInfoGenerator(IStore<X509Certificate> x509Certs, IStore<X509Crl> x509Crls) + : this(x509Certs, x509Crls, null, null) { - this.origCerts = CmsUtilities.GetCertificatesFromStore(origCerts); - this.origCrls = origCrls == null ? null : CmsUtilities.GetCrlsFromStore(origCrls); } - + + public OriginatorInfoGenerator(IStore<X509Certificate> x509Certs, IStore<X509Crl> x509Crls, + IStore<X509V2AttributeCertificate> x509AttrCerts, IStore<OtherRevocationInfoFormat> otherRevocationInfos) + { + List<Asn1Encodable> certificates = null; + if (x509Certs != null || x509AttrCerts != null) + { + certificates = new List<Asn1Encodable>(); + if (x509Certs != null) + { + certificates.AddRange(CmsUtilities.GetCertificatesFromStore(x509Certs)); + } + if (x509AttrCerts != null) + { + certificates.AddRange(CmsUtilities.GetAttributeCertificatesFromStore(x509AttrCerts)); + } + } + + List<Asn1Encodable> revocations = null; + if (x509Crls != null || otherRevocationInfos != null) + { + revocations = new List<Asn1Encodable>(); + if (x509Crls != null) + { + revocations.AddRange(CmsUtilities.GetCrlsFromStore(x509Crls)); + } + if (otherRevocationInfos != null) + { + revocations.AddRange(CmsUtilities.GetOtherRevocationInfosFromStore(otherRevocationInfos)); + } + } + + this.origCerts = certificates; + this.origCrls = revocations; + } + public virtual OriginatorInfo Generate() { - Asn1Set certSet = CmsUtilities.CreateDerSetFromList(origCerts); + Asn1Set certSet = origCerts == null ? null : CmsUtilities.CreateDerSetFromList(origCerts); Asn1Set crlSet = origCrls == null ? null : CmsUtilities.CreateDerSetFromList(origCrls); return new OriginatorInfo(certSet, crlSet); } |