summary refs log tree commit diff
path: root/crypto/src/asn1/cms/AuthenticatedData.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2024-06-18 16:12:06 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2024-06-18 16:12:06 +0700
commit740c25a020c7539c99e82dd4531492c5b6bbd787 (patch)
tree998874b3c9d7b80636919b44de639218c9622f29 /crypto/src/asn1/cms/AuthenticatedData.cs
parentDerInteger constants for small values (diff)
downloadBouncyCastle.NET-ed25519-740c25a020c7539c99e82dd4531492c5b6bbd787.tar.xz
Refactoring in Asn1.Cms
Diffstat (limited to 'crypto/src/asn1/cms/AuthenticatedData.cs')
-rw-r--r--crypto/src/asn1/cms/AuthenticatedData.cs283
1 files changed, 123 insertions, 160 deletions
diff --git a/crypto/src/asn1/cms/AuthenticatedData.cs b/crypto/src/asn1/cms/AuthenticatedData.cs
index 47db0fa16..fad7de35f 100644
--- a/crypto/src/asn1/cms/AuthenticatedData.cs
+++ b/crypto/src/asn1/cms/AuthenticatedData.cs
@@ -21,132 +21,73 @@ namespace Org.BouncyCastle.Asn1.Cms
             return new AuthenticatedData(Asn1Sequence.GetInstance(obj, isExplicit));
         }
 
-        private DerInteger version;
-		private OriginatorInfo originatorInfo;
-		private Asn1Set recipientInfos;
-		private AlgorithmIdentifier macAlgorithm;
-		private AlgorithmIdentifier digestAlgorithm;
-		private ContentInfo encapsulatedContentInfo;
-		private Asn1Set authAttrs;
-		private Asn1OctetString mac;
-		private Asn1Set unauthAttrs;
-
-		public AuthenticatedData(
-			OriginatorInfo		originatorInfo,
-			Asn1Set				recipientInfos,
-			AlgorithmIdentifier	macAlgorithm,
-			AlgorithmIdentifier	digestAlgorithm,
-			ContentInfo			encapsulatedContent,
-			Asn1Set				authAttrs,
-			Asn1OctetString		mac,
-			Asn1Set				unauthAttrs)
-		{
-			if (digestAlgorithm != null || authAttrs != null)
-			{
-				if (digestAlgorithm == null || authAttrs == null)
-				{
-					throw new ArgumentException("digestAlgorithm and authAttrs must be set together");
-				}
-			}
-
-			version = new DerInteger(CalculateVersion(originatorInfo));
-
-			this.originatorInfo = originatorInfo;
-			this.macAlgorithm = macAlgorithm;
-			this.digestAlgorithm = digestAlgorithm;
-			this.recipientInfos = recipientInfos;
-			this.encapsulatedContentInfo = encapsulatedContent;
-			this.authAttrs = authAttrs;
-			this.mac = mac;
-			this.unauthAttrs = unauthAttrs;
-		}
+        private readonly DerInteger m_version;
+        private readonly OriginatorInfo m_originatorInfo;
+        private readonly Asn1Set m_recipientInfos;
+        private readonly AlgorithmIdentifier m_macAlgorithm;
+        private readonly AlgorithmIdentifier m_digestAlgorithm;
+        private readonly ContentInfo m_encapsulatedContentInfo;
+        private readonly Asn1Set m_authAttrs;
+        private readonly Asn1OctetString m_mac;
+        private readonly Asn1Set m_unauthAttrs;
+
+        public AuthenticatedData(OriginatorInfo originatorInfo, Asn1Set recipientInfos,
+			AlgorithmIdentifier macAlgorithm, AlgorithmIdentifier digestAlgorithm, ContentInfo encapsulatedContent,
+            Asn1Set authAttrs, Asn1OctetString mac, Asn1Set unauthAttrs)
+        {
+            if ((digestAlgorithm == null) != (authAttrs == null))
+                throw new ArgumentException("digestAlgorithm and authAttrs must be set together");
+
+            m_version = CalculateVersionField(originatorInfo);
+            m_originatorInfo = originatorInfo;
+            m_macAlgorithm = macAlgorithm ?? throw new ArgumentNullException(nameof(macAlgorithm));
+            m_digestAlgorithm = digestAlgorithm;
+            m_recipientInfos = recipientInfos ?? throw new ArgumentNullException(nameof(recipientInfos));
+            m_encapsulatedContentInfo = encapsulatedContent ?? throw new ArgumentNullException(nameof(encapsulatedContent));
+            m_authAttrs = authAttrs;
+            m_mac = mac ?? throw new ArgumentNullException(nameof(mac));
+            m_unauthAttrs = unauthAttrs;
+        }
 
-		private AuthenticatedData(Asn1Sequence seq)
+        private AuthenticatedData(Asn1Sequence seq)
 		{
-			int index = 0;
-
-			version = (DerInteger)seq[index++];
-
-			Asn1Encodable tmp = seq[index++];
-			if (tmp is Asn1TaggedObject taggedObject1)
-			{
-				originatorInfo = OriginatorInfo.GetInstance(taggedObject1, false);
-				tmp = seq[index++];
-			}
-
-			recipientInfos = Asn1Set.GetInstance(tmp);
-			macAlgorithm = AlgorithmIdentifier.GetInstance(seq[index++]);
-
-			tmp = seq[index++];
-			if (tmp is Asn1TaggedObject taggedObject2)
-			{
-				digestAlgorithm = AlgorithmIdentifier.GetInstance(taggedObject2, false);
-				tmp = seq[index++];
-			}
-
-			encapsulatedContentInfo = ContentInfo.GetInstance(tmp);
-
-			tmp = seq[index++];
-			if (tmp is Asn1TaggedObject taggedObject3)
-			{
-				authAttrs = Asn1Set.GetInstance(taggedObject3, false);
-				tmp = seq[index++];
-			}
-
-			mac = Asn1OctetString.GetInstance(tmp);
-
-			if (seq.Count > index)
-			{
-				unauthAttrs = Asn1Set.GetInstance((Asn1TaggedObject)seq[index], false);
-			}
+            int count = seq.Count, pos = 0;
+            if (count < 5 || count > 9)
+                throw new ArgumentException("Bad sequence size: " + count, nameof(seq));
+
+            m_version = DerInteger.GetInstance(seq[pos++]);
+            m_originatorInfo = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 0, false, OriginatorInfo.GetInstance);
+            m_recipientInfos = Asn1Set.GetInstance(seq[pos++]);
+            m_macAlgorithm = AlgorithmIdentifier.GetInstance(seq[pos++]);
+            m_digestAlgorithm = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 1, false, AlgorithmIdentifier.GetInstance);
+            m_encapsulatedContentInfo = ContentInfo.GetInstance(seq[pos++]);
+            m_authAttrs = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 2, false, Asn1Set.GetInstance);
+            m_mac = Asn1OctetString.GetInstance(seq[pos++]);
+            m_unauthAttrs = Asn1Utilities.ReadOptionalContextTagged(seq, ref pos, 3, false, Asn1Set.GetInstance);
+
+            if (pos != count)
+                throw new ArgumentException("Unexpected elements in sequence", nameof(seq));
 		}
 
-        public DerInteger Version
-		{
-			get { return version; }
-		}
+        public DerInteger Version => m_version;
 
-		public OriginatorInfo OriginatorInfo
-		{
-			get { return originatorInfo; }
-		}
+        public OriginatorInfo OriginatorInfo => m_originatorInfo;
 
-		public Asn1Set RecipientInfos
-		{
-			get { return recipientInfos; }
-		}
+        public Asn1Set RecipientInfos => m_recipientInfos;
 
-		public AlgorithmIdentifier MacAlgorithm
-		{
-			get { return macAlgorithm; }
-		}
+        public AlgorithmIdentifier MacAlgorithm => m_macAlgorithm;
 
-        public AlgorithmIdentifier DigestAlgorithm
-        {
-            get { return digestAlgorithm; }
-        }
+        public AlgorithmIdentifier DigestAlgorithm => m_digestAlgorithm;
 
-		public ContentInfo EncapsulatedContentInfo
-		{
-			get { return encapsulatedContentInfo; }
-		}
+        public ContentInfo EncapsulatedContentInfo => m_encapsulatedContentInfo;
 
-		public Asn1Set AuthAttrs
-		{
-			get { return authAttrs; }
-		}
+        public Asn1Set AuthAttrs => m_authAttrs;
 
-		public Asn1OctetString Mac
-		{
-			get { return mac; }
-		}
+        public Asn1OctetString Mac => m_mac;
 
-		public Asn1Set UnauthAttrs
-		{
-			get { return unauthAttrs; }
-		}
+        public Asn1Set UnauthAttrs => m_unauthAttrs;
 
-		/**
+        /**
 		 * Produce an object suitable for an Asn1OutputStream.
 		 * <pre>
 		 * AuthenticatedData ::= SEQUENCE {
@@ -167,55 +108,77 @@ namespace Org.BouncyCastle.Asn1.Cms
 		 * MessageAuthenticationCode ::= OCTET STRING
 		 * </pre>
 		 */
-		public override Asn1Object ToAsn1Object()
-		{
-			Asn1EncodableVector v = new Asn1EncodableVector(version);
-            v.AddOptionalTagged(false, 0, originatorInfo);
-			v.Add(recipientInfos, macAlgorithm);
-            v.AddOptionalTagged(false, 1, digestAlgorithm);
-			v.Add(encapsulatedContentInfo);
-            v.AddOptionalTagged(false, 2, authAttrs);
-			v.Add(mac);
-            v.AddOptionalTagged(false, 3, unauthAttrs);
-			return new BerSequence(v);
-		}
+        public override Asn1Object ToAsn1Object()
+        {
+            Asn1EncodableVector v = new Asn1EncodableVector(9);
+            v.Add(m_version);
+            v.AddOptionalTagged(false, 0, m_originatorInfo);
+            v.Add(m_recipientInfos, m_macAlgorithm);
+            v.AddOptionalTagged(false, 1, m_digestAlgorithm);
+            v.Add(m_encapsulatedContentInfo);
+            v.AddOptionalTagged(false, 2, m_authAttrs);
+            v.Add(m_mac);
+            v.AddOptionalTagged(false, 3, m_unauthAttrs);
+            return new BerSequence(v);
+        }
+
+        public static int CalculateVersion(OriginatorInfo origInfo) => CalculateVersionField(origInfo).IntValueExact;
 
-		public static int CalculateVersion(OriginatorInfo origInfo)
+        private static DerInteger CalculateVersionField(OriginatorInfo originatorInfo)
 		{
-			if (origInfo == null)
-				return 0;
-
-			int ver = 0;
-
-			foreach (object obj in origInfo.Certificates)
-			{
-				if (obj is Asn1TaggedObject tag)
-				{
-					if (tag.TagNo == 2)
-					{
-						ver = 1;
-					}
-					else if (tag.TagNo == 3)
-					{
-						ver = 3;
-						break;
-					}
-				}
-			}
-
-			foreach (object obj in origInfo.Crls)
-			{
-				if (obj is Asn1TaggedObject tag)
-				{
-					if (tag.TagNo == 1)
-					{
-						ver = 3;
-						break;
-					}
-				}
-			}
-
-			return ver;
+            /*
+             * IF (originatorInfo is present) AND
+             *    ((any certificates with a type of other are present) OR
+             *    (any crls with a type of other are present))
+             * THEN version is 3
+             * ELSE
+             *    IF ((originatorInfo is present) AND
+             *       (any version 2 attribute certificates are present))
+             *    THEN version is 1
+             *    ELSE version is 0
+             */
+
+            if (originatorInfo != null)
+            {
+                var crls = originatorInfo.Crls;
+                if (crls != null)
+                {
+                    foreach (var element in crls)
+                    {
+                        var tagged = Asn1TaggedObject.GetOptional(element);
+                        if (tagged != null)
+                        {
+                            // RevocationInfoChoice.other
+                            if (tagged.HasContextTag(1))
+                                return DerInteger.Three;
+                        }
+                    }
+                }
+
+                var certs = originatorInfo.Certificates;
+                if (certs != null)
+                {
+                    bool anyV2AttrCerts = false;
+
+                    foreach (var element in certs)
+                    {
+                        var tagged = Asn1TaggedObject.GetOptional(element);
+                        if (tagged != null)
+                        {
+                            // CertificateChoices.other
+                            if (tagged.HasContextTag(3))
+                                return DerInteger.Three;
+
+                            // CertificateChoices.v2AttrCert
+                            anyV2AttrCerts = anyV2AttrCerts || tagged.HasContextTag(2);
+                        }
+                    }
+
+                    if (anyV2AttrCerts)
+                        return DerInteger.One;
+                }
+            }
+            return DerInteger.Zero;
 		}
 	}
 }