From 27f48072133d8ae91291907fab83130853c840c2 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 25 Jul 2023 18:15:43 +0700 Subject: Refactoring around algorithm finders --- crypto/src/cmp/CertificateConfirmationContent.cs | 40 ++++++++++++---------- .../cmp/CertificateConfirmationContentBuilder.cs | 23 +++++-------- crypto/src/cmp/CertificateStatus.cs | 17 ++++----- crypto/src/cms/CMSSignedData.cs | 6 ++-- crypto/src/cms/CMSSignedDataGenerator.cs | 4 +-- crypto/src/cms/CMSSignedGenerator.cs | 26 ++++++-------- crypto/test/src/cmp/test/ProtectedMessageTest.cs | 2 +- 7 files changed, 52 insertions(+), 66 deletions(-) diff --git a/crypto/src/cmp/CertificateConfirmationContent.cs b/crypto/src/cmp/CertificateConfirmationContent.cs index ceb34e2c8..13db89c37 100644 --- a/crypto/src/cmp/CertificateConfirmationContent.cs +++ b/crypto/src/cmp/CertificateConfirmationContent.cs @@ -7,36 +7,38 @@ namespace Org.BouncyCastle.Cmp { public class CertificateConfirmationContent { - private readonly DefaultDigestAlgorithmIdentifierFinder m_digestAlgFinder; + public static CertificateConfirmationContent FromPkiBody(PkiBody pkiBody) => + FromPkiBody(pkiBody, DefaultDigestAlgorithmIdentifierFinder.Instance); + + public static CertificateConfirmationContent FromPkiBody(PkiBody pkiBody, + DefaultDigestAlgorithmIdentifierFinder digestAlgFinder) + { + if (!IsCertificateConfirmationContent(pkiBody.Type)) + throw new ArgumentException("content of PkiBody wrong type: " + pkiBody.Type); + + return new CertificateConfirmationContent(CertConfirmContent.GetInstance(pkiBody.Content), digestAlgFinder); + } + + public static bool IsCertificateConfirmationContent(int bodyType) => PkiBody.TYPE_CERT_CONFIRM == bodyType; + private readonly CertConfirmContent m_content; + private readonly DefaultDigestAlgorithmIdentifierFinder m_digestAlgIDFinder; public CertificateConfirmationContent(CertConfirmContent content) + : this(content, DefaultDigestAlgorithmIdentifierFinder.Instance) { - this.m_content = content; } public CertificateConfirmationContent(CertConfirmContent content, DefaultDigestAlgorithmIdentifierFinder digestAlgFinder) { - this.m_content = content; - this.m_digestAlgFinder = digestAlgFinder; + m_content = content; + m_digestAlgIDFinder = digestAlgFinder; } - public CertConfirmContent ToAsn1Structure() - { - return m_content; - } + public CertConfirmContent ToAsn1Structure() => m_content; - public CertificateStatus[] GetStatusMessages() - { - CertStatus[] statusArray = m_content.ToCertStatusArray(); - CertificateStatus[] ret = new CertificateStatus[statusArray.Length]; - for (int i = 0; i != ret.Length; i++) - { - ret[i] = new CertificateStatus(m_digestAlgFinder, statusArray[i]); - } - - return ret; - } + public CertificateStatus[] GetStatusMessages() => Array.ConvertAll(m_content.ToCertStatusArray(), + element => new CertificateStatus(m_digestAlgIDFinder, element)); } } diff --git a/crypto/src/cmp/CertificateConfirmationContentBuilder.cs b/crypto/src/cmp/CertificateConfirmationContentBuilder.cs index 09ae71bbf..4178264b4 100644 --- a/crypto/src/cmp/CertificateConfirmationContentBuilder.cs +++ b/crypto/src/cmp/CertificateConfirmationContentBuilder.cs @@ -12,21 +12,18 @@ namespace Org.BouncyCastle.Cmp { public sealed class CertificateConfirmationContentBuilder { - private static readonly DefaultSignatureAlgorithmIdentifierFinder SigAlgFinder = - new DefaultSignatureAlgorithmIdentifierFinder(); - private readonly DefaultDigestAlgorithmIdentifierFinder m_digestAlgFinder; - private readonly IList m_acceptedCerts = new List(); - private readonly IList m_acceptedReqIDs = new List(); + private readonly List m_acceptedCerts = new List(); + private readonly List m_acceptedReqIDs = new List(); public CertificateConfirmationContentBuilder() - : this(new DefaultDigestAlgorithmIdentifierFinder()) + : this(DefaultDigestAlgorithmIdentifierFinder.Instance) { } public CertificateConfirmationContentBuilder(DefaultDigestAlgorithmIdentifierFinder digestAlgFinder) { - this.m_digestAlgFinder = digestAlgFinder; + m_digestAlgFinder = digestAlgFinder; } public CertificateConfirmationContentBuilder AddAcceptedCertificate(X509Certificate certHolder, @@ -45,15 +42,13 @@ namespace Org.BouncyCastle.Cmp X509Certificate cert = m_acceptedCerts[i]; BigInteger reqID = m_acceptedReqIDs[i]; - AlgorithmIdentifier algorithmIdentifier = SigAlgFinder.Find(cert.SigAlgName); - if (null == algorithmIdentifier) - throw new CmpException("cannot find algorithm identifier for signature name"); + var sigAlgID = DefaultSignatureAlgorithmIdentifierFinder.Instance.Find(cert.SigAlgName) + ?? throw new CmpException("cannot find algorithm identifier for signature name"); - AlgorithmIdentifier digAlg = m_digestAlgFinder.Find(algorithmIdentifier); - if (null == digAlg) - throw new CmpException("cannot find algorithm for digest from signature"); + AlgorithmIdentifier digAlgID = m_digestAlgFinder.Find(sigAlgID) + ?? throw new CmpException("cannot find algorithm for digest from signature"); - byte[] digest = DigestUtilities.CalculateDigest(digAlg.Algorithm, cert.GetEncoded()); + byte[] digest = DigestUtilities.CalculateDigest(digAlgID.Algorithm, cert.GetEncoded()); v.Add(new CertStatus(digest, reqID)); } diff --git a/crypto/src/cmp/CertificateStatus.cs b/crypto/src/cmp/CertificateStatus.cs index 53227d062..8ccf89562 100644 --- a/crypto/src/cmp/CertificateStatus.cs +++ b/crypto/src/cmp/CertificateStatus.cs @@ -1,9 +1,6 @@ -using System; - -using Org.BouncyCastle.Asn1.Cmp; +using Org.BouncyCastle.Asn1.Cmp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Cms; -using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; @@ -13,8 +10,6 @@ namespace Org.BouncyCastle.Cmp { public class CertificateStatus { - private static readonly DefaultSignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); - private readonly DefaultDigestAlgorithmIdentifierFinder digestAlgFinder; private readonly CertStatus certStatus; @@ -30,11 +25,13 @@ namespace Org.BouncyCastle.Cmp public virtual bool IsVerified(X509Certificate cert) { - AlgorithmIdentifier digAlg = digestAlgFinder.Find(sigAlgFinder.Find(cert.SigAlgName)); - if (null == digAlg) - throw new CmpException("cannot find algorithm for digest from signature " + cert.SigAlgName); + var sigAlgID = DefaultSignatureAlgorithmIdentifierFinder.Instance.Find(cert.SigAlgName) + ?? throw new CmpException("cannot find algorithm identifier for signature name"); + + var digAlgID = digestAlgFinder.Find(sigAlgID) + ?? throw new CmpException("cannot find algorithm for digest from signature " + cert.SigAlgName); - byte[] digest = DigestUtilities.CalculateDigest(digAlg.Algorithm, cert.GetEncoded()); + byte[] digest = DigestUtilities.CalculateDigest(digAlgID.Algorithm, cert.GetEncoded()); return Arrays.FixedTimeEquals(certStatus.CertHash.GetOctets(), digest); } diff --git a/crypto/src/cms/CMSSignedData.cs b/crypto/src/cms/CMSSignedData.cs index bfe4705e7..cd517085c 100644 --- a/crypto/src/cms/CMSSignedData.cs +++ b/crypto/src/cms/CMSSignedData.cs @@ -36,8 +36,6 @@ namespace Org.BouncyCastle.Cms public class CmsSignedData { private static readonly CmsSignedHelper Helper = CmsSignedHelper.Instance; - internal static readonly DefaultDigestAlgorithmIdentifierFinder DigestAlgIDFinder = - new DefaultDigestAlgorithmIdentifierFinder(); private readonly CmsProcessable signedContent; private SignedData signedData; @@ -280,7 +278,7 @@ namespace Org.BouncyCastle.Cms * @return a new signed data object. */ public static CmsSignedData AddDigestAlgorithm(CmsSignedData signedData, AlgorithmIdentifier digestAlgorithm) => - AddDigestAlgorithm(signedData, digestAlgorithm, DigestAlgIDFinder); + AddDigestAlgorithm(signedData, digestAlgorithm, DefaultDigestAlgorithmIdentifierFinder.Instance); /** * Return a new CMSSignedData which guarantees to have the passed in digestAlgorithm @@ -355,7 +353,7 @@ namespace Org.BouncyCastle.Cms */ public static CmsSignedData ReplaceSigners(CmsSignedData signedData, SignerInformationStore signerInformationStore) => - ReplaceSigners(signedData, signerInformationStore, DigestAlgIDFinder); + ReplaceSigners(signedData, signerInformationStore, DefaultDigestAlgorithmIdentifierFinder.Instance); /** * Replace the SignerInformation store associated with this CMSSignedData object with the new one passed in diff --git a/crypto/src/cms/CMSSignedDataGenerator.cs b/crypto/src/cms/CMSSignedDataGenerator.cs index 015c540cd..ec8e28e47 100644 --- a/crypto/src/cms/CMSSignedDataGenerator.cs +++ b/crypto/src/cms/CMSSignedDataGenerator.cs @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Cms this.outer = outer; this.sigCalc = sigCalc; this.signerIdentifier = signerIdentifier; - this.digestOID = new DefaultDigestAlgorithmIdentifierFinder().Find( + this.digestOID = DefaultDigestAlgorithmIdentifierFinder.Instance.Find( (AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id; this.encOID = ((AlgorithmIdentifier)sigCalc.AlgorithmDetails).Algorithm.Id; this.sAttr = sAttr; @@ -457,7 +457,7 @@ namespace Org.BouncyCastle.Cms // foreach (SignerInformation signer in _signers) { - CmsUtilities.AddDigestAlgs(digestAlgs, signer, CmsSignedData.DigestAlgIDFinder); + CmsUtilities.AddDigestAlgs(digestAlgs, signer, DefaultDigestAlgorithmIdentifierFinder.Instance); // TODO Verify the content type and calculated digest match the precalculated SignerInfo signerInfos.Add(signer.ToSignerInfo()); } diff --git a/crypto/src/cms/CMSSignedGenerator.cs b/crypto/src/cms/CMSSignedGenerator.cs index f49b1fb80..5cb56805f 100644 --- a/crypto/src/cms/CMSSignedGenerator.cs +++ b/crypto/src/cms/CMSSignedGenerator.cs @@ -28,6 +28,9 @@ namespace Org.BouncyCastle.Cms // TODO[api] Create API for this public class DefaultSignatureAlgorithmIdentifierFinder { + public static readonly DefaultSignatureAlgorithmIdentifierFinder Instance = + new DefaultSignatureAlgorithmIdentifierFinder(); + private static readonly Dictionary m_algorithms = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly HashSet m_noParams = new HashSet(); @@ -509,8 +512,7 @@ namespace Org.BouncyCastle.Cms // TODO[api] Make virtual public AlgorithmIdentifier Find(string sigAlgName) { - string algorithmName = sigAlgName.ToUpperInvariant(); - if (!m_algorithms.TryGetValue(algorithmName, out var sigAlgOid)) + if (!m_algorithms.TryGetValue(sigAlgName, out var sigAlgOid)) throw new ArgumentException("Unknown signature type requested: " + sigAlgName, nameof(sigAlgName)); AlgorithmIdentifier sigAlgID; @@ -518,7 +520,7 @@ namespace Org.BouncyCastle.Cms { sigAlgID = new AlgorithmIdentifier(sigAlgOid); } - else if (m_parameters.TryGetValue(algorithmName, out var parameters)) + else if (m_parameters.TryGetValue(sigAlgName, out var parameters)) { sigAlgID = new AlgorithmIdentifier(sigAlgOid, parameters); } @@ -533,6 +535,9 @@ namespace Org.BouncyCastle.Cms // TODO[api] Create API for this public class DefaultDigestAlgorithmIdentifierFinder { + public static readonly DefaultDigestAlgorithmIdentifierFinder Instance = + new DefaultDigestAlgorithmIdentifierFinder(); + private static readonly Dictionary m_digestOids = new Dictionary(); private static readonly Dictionary m_digestNameToOids = @@ -768,19 +773,8 @@ namespace Org.BouncyCastle.Cms m_shake256Oids.Add(BCObjectIdentifiers.falcon_1024); } - private static void AddDigestAlgID(DerObjectIdentifier oid, bool withNullParams) - { - AlgorithmIdentifier algID; - if (withNullParams) - { - algID = new AlgorithmIdentifier(oid, DerNull.Instance); - } - else - { - algID = new AlgorithmIdentifier(oid); - } - m_digestOidToAlgIDs.Add(oid, algID); - } + private static void AddDigestAlgID(DerObjectIdentifier oid, bool withNullParams) => + m_digestOidToAlgIDs.Add(oid, new AlgorithmIdentifier(oid, withNullParams ? DerNull.Instance : null)); // TODO[api] Make virtual public AlgorithmIdentifier Find(AlgorithmIdentifier sigAlgId) diff --git a/crypto/test/src/cmp/test/ProtectedMessageTest.cs b/crypto/test/src/cmp/test/ProtectedMessageTest.cs index e2df4eb40..a63f94f75 100644 --- a/crypto/test/src/cmp/test/ProtectedMessageTest.cs +++ b/crypto/test/src/cmp/test/ProtectedMessageTest.cs @@ -167,7 +167,7 @@ namespace Org.BouncyCastle.Cmp.Tests IsEquals(sender, msg.Header.Sender); IsEquals(recipient, msg.Header.Recipient); - content = new CertificateConfirmationContent(CertConfirmContent.GetInstance(msg.Body.Content), new DefaultDigestAlgorithmIdentifierFinder()); + content = new CertificateConfirmationContent(CertConfirmContent.GetInstance(msg.Body.Content)); CertificateStatus[] statusList = content.GetStatusMessages(); IsEquals(1, statusList.Length); IsTrue(statusList[0].IsVerified(cert)); -- cgit 1.4.1