summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/asn1/cms/CMSAttributes.cs2
-rw-r--r--crypto/src/asn1/cms/CmsAlgorithmProtection.cs105
-rw-r--r--crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs5
-rw-r--r--crypto/src/cms/CMSAttributeTableGenerator.cs9
4 files changed, 114 insertions, 7 deletions
diff --git a/crypto/src/asn1/cms/CMSAttributes.cs b/crypto/src/asn1/cms/CMSAttributes.cs
index fca2b6738..a3e11db84 100644
--- a/crypto/src/asn1/cms/CMSAttributes.cs
+++ b/crypto/src/asn1/cms/CMSAttributes.cs
@@ -10,5 +10,7 @@ namespace Org.BouncyCastle.Asn1.Cms
         public static readonly DerObjectIdentifier SigningTime		= PkcsObjectIdentifiers.Pkcs9AtSigningTime;
 		public static readonly DerObjectIdentifier CounterSignature = PkcsObjectIdentifiers.Pkcs9AtCounterSignature;
 		public static readonly DerObjectIdentifier ContentHint		= PkcsObjectIdentifiers.IdAAContentHint;
+        public static readonly DerObjectIdentifier CmsAlgorithmProtect = PkcsObjectIdentifiers.id_aa_cmsAlgorithmProtect;
+
 	}
 }
diff --git a/crypto/src/asn1/cms/CmsAlgorithmProtection.cs b/crypto/src/asn1/cms/CmsAlgorithmProtection.cs
new file mode 100644
index 000000000..9d21e53ff
--- /dev/null
+++ b/crypto/src/asn1/cms/CmsAlgorithmProtection.cs
@@ -0,0 +1,105 @@
+using System;
+
+using Org.BouncyCastle.Asn1.X509;
+
+namespace Org.BouncyCastle.Asn1.Cms
+{
+
+    /**
+     * From RFC 6211
+     * <pre>
+     * CMSAlgorithmProtection ::= SEQUENCE {
+     *    digestAlgorithm         DigestAlgorithmIdentifier,
+     *    signatureAlgorithm  [1] SignatureAlgorithmIdentifier OPTIONAL,
+     *    macAlgorithm        [2] MessageAuthenticationCodeAlgorithm
+     *                                     OPTIONAL
+     * }
+     * (WITH COMPONENTS { signatureAlgorithm PRESENT,
+     *                    macAlgorithm ABSENT } |
+     *  WITH COMPONENTS { signatureAlgorithm ABSENT,
+     *                    macAlgorithm PRESENT })
+     * </pre>
+     */
+    public class CmsAlgorithmProtection
+        : Asn1Encodable
+    {
+        public static readonly int Signature = 1;
+        public static readonly int Mac = 2;
+
+        private readonly AlgorithmIdentifier digestAlgorithm;
+        private readonly AlgorithmIdentifier signatureAlgorithm;
+        private readonly AlgorithmIdentifier macAlgorithm;
+
+        public CmsAlgorithmProtection(AlgorithmIdentifier digestAlgorithm, int type, AlgorithmIdentifier algorithmIdentifier)
+        {
+            if (digestAlgorithm == null || algorithmIdentifier == null)
+                throw new ArgumentException("AlgorithmIdentifiers cannot be null");
+
+            this.digestAlgorithm = digestAlgorithm;
+
+            if (type == 1)
+            {
+                this.signatureAlgorithm = algorithmIdentifier;
+                this.macAlgorithm = null;
+            }
+            else if (type == 2)
+            {
+                this.signatureAlgorithm = null;
+                this.macAlgorithm = algorithmIdentifier;
+            }
+            else
+            {
+                throw new ArgumentException("Unknown type: " + type);
+            }
+        }
+
+        private CmsAlgorithmProtection(Asn1Sequence sequence)
+        {
+            if (sequence.Count != 2)
+                throw new ArgumentException("Sequence wrong size: One of signatureAlgorithm or macAlgorithm must be present");
+
+            this.digestAlgorithm = AlgorithmIdentifier.GetInstance(sequence[0]);
+
+            Asn1TaggedObject tagged = Asn1TaggedObject.GetInstance(sequence[1]);
+            if (tagged.TagNo == 1)
+            {
+                this.signatureAlgorithm = AlgorithmIdentifier.GetInstance(tagged, false);
+                this.macAlgorithm = null;
+            }
+            else if (tagged.TagNo == 2)
+            {
+                this.signatureAlgorithm = null;
+
+                this.macAlgorithm = AlgorithmIdentifier.GetInstance(tagged, false);
+            }
+            else
+            {
+                throw new ArgumentException("Unknown tag found: " + tagged.TagNo);
+            }
+        }
+
+        public static CmsAlgorithmProtection GetInstance(object obj)
+        {
+            if (obj == null)
+                return null;
+            if (obj is CmsAlgorithmProtection cmsAlgorithmProtection)
+                return cmsAlgorithmProtection;
+            return new CmsAlgorithmProtection(Asn1Sequence.GetInstance(obj));
+        }
+
+        public AlgorithmIdentifier DigestAlgorithm => digestAlgorithm;
+
+        public AlgorithmIdentifier MacAlgorithm => macAlgorithm;
+
+        public AlgorithmIdentifier SignatureAlgorithm => signatureAlgorithm;
+
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(3);
+            v.Add(digestAlgorithm);
+            v.AddOptionalTagged(false, 1, signatureAlgorithm);
+            v.AddOptionalTagged(false, 2, macAlgorithm);
+            return new DerSequence(v);
+        }
+    }
+}
diff --git a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs
index 570e0ded7..5d5f67127 100644
--- a/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs
+++ b/crypto/src/asn1/pkcs/PKCSObjectIdentifiers.cs
@@ -145,6 +145,11 @@ namespace Org.BouncyCastle.Asn1.Pkcs
         public static readonly DerObjectIdentifier IdAlgPwriKek         = IdAlg.Branch("9");
         public static readonly DerObjectIdentifier IdAlgSsdh            = IdAlg.Branch("10");
 
+        /** RFC 6211 -  id-aa-cmsAlgorithmProtect OBJECT IDENTIFIER ::= {
+iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+pkcs9(9) 52 }  */
+        public static readonly DerObjectIdentifier id_aa_cmsAlgorithmProtect = new DerObjectIdentifier(Pkcs9 + ".52");
+
         /*
          * <pre>
          * -- RSA-KEM Key Transport Algorithm
diff --git a/crypto/src/cms/CMSAttributeTableGenerator.cs b/crypto/src/cms/CMSAttributeTableGenerator.cs
index a113bd8d4..36d1bdcff 100644
--- a/crypto/src/cms/CMSAttributeTableGenerator.cs
+++ b/crypto/src/cms/CMSAttributeTableGenerator.cs
@@ -9,13 +9,8 @@ namespace Org.BouncyCastle.Cms
 	/// </remarks>
 	public enum CmsAttributeTableParameter
 	{
-//		const string ContentType = "contentType";
-//		const string Digest = "digest";
-//		const string Signature = "encryptedDigest";
-//		const string DigestAlgorithmIdentifier = "digestAlgID";
-
-		ContentType, Digest, Signature, DigestAlgorithmIdentifier
-	}
+		ContentType, Digest, Signature, DigestAlgorithmIdentifier, SignatureAlgorithmIdentifier
+    }
 
 	public interface CmsAttributeTableGenerator
 	{