summary refs log tree commit diff
path: root/crypto/src/cms
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-06 17:43:41 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-06 17:43:41 +0700
commitc1d0de54d5ae25ea78cde7ff30e58a5fd07e089c (patch)
treef2d77abd46e1004d7f0d765bd619e49501c1024c /crypto/src/cms
parentAsn1 GetInstance refactoring (diff)
downloadBouncyCastle.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.cs62
-rw-r--r--crypto/src/cms/CMSSignedDataParser.cs9
-rw-r--r--crypto/src/cms/CMSSignedGenerator.cs17
-rw-r--r--crypto/src/cms/CMSSignedHelper.cs26
-rw-r--r--crypto/src/cms/CMSUtils.cs52
-rw-r--r--crypto/src/cms/OriginatorInfoGenerator.cs59
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);
         }