From 740c25a020c7539c99e82dd4531492c5b6bbd787 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 18 Jun 2024 16:12:06 +0700 Subject: Refactoring in Asn1.Cms --- crypto/src/asn1/cms/AuthenticatedData.cs | 283 ++++++++++++++----------------- 1 file changed, 123 insertions(+), 160 deletions(-) (limited to 'crypto/src/asn1/cms/AuthenticatedData.cs') 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. *
 		 * AuthenticatedData ::= SEQUENCE {
@@ -167,55 +108,77 @@ namespace Org.BouncyCastle.Asn1.Cms
 		 * MessageAuthenticationCode ::= OCTET STRING
 		 * 
*/ - 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; } } } -- cgit 1.4.1