From 0f3b8a392bc23cc1b9a4320987e61c3f64b0639a Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 28 Jul 2023 13:04:07 +0700 Subject: Refactoring around digest calculation --- .../cmp/CertificateConfirmationContentBuilder.cs | 15 ++--- crypto/src/cmp/CertificateStatus.cs | 10 +--- crypto/src/cmp/CmpUtilities.cs | 18 ++++++ crypto/src/crypto/operators/Asn1DigestFactory.cs | 64 ++++------------------ .../crypto/operators/DefaultDigestCalculator.cs | 21 +++++++ crypto/src/crypto/operators/DefaultDigestResult.cs | 27 +++++++++ crypto/src/x509/X509Utilities.cs | 15 +++++ 7 files changed, 98 insertions(+), 72 deletions(-) create mode 100644 crypto/src/cmp/CmpUtilities.cs create mode 100644 crypto/src/crypto/operators/DefaultDigestCalculator.cs create mode 100644 crypto/src/crypto/operators/DefaultDigestResult.cs (limited to 'crypto') diff --git a/crypto/src/cmp/CertificateConfirmationContentBuilder.cs b/crypto/src/cmp/CertificateConfirmationContentBuilder.cs index faf0cf998..873b58b2e 100644 --- a/crypto/src/cmp/CertificateConfirmationContentBuilder.cs +++ b/crypto/src/cmp/CertificateConfirmationContentBuilder.cs @@ -6,7 +6,6 @@ using Org.BouncyCastle.Asn1.Cmp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; using Org.BouncyCastle.Operators.Utilities; -using Org.BouncyCastle.Security; using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Cmp @@ -62,17 +61,11 @@ namespace Org.BouncyCastle.Cmp Asn1EncodableVector v = new Asn1EncodableVector(m_acceptedCerts.Count); for (int i = 0; i != m_acceptedCerts.Count; i++) { - CmpCertificate cmpCertificate = m_acceptedCerts[i]; - AlgorithmIdentifier signatureAlgorithm = m_acceptedSignatureAlgorithms[i]; - DerInteger reqID = m_acceptedReqIDs[i]; + var certHash = CmpUtilities.CalculateCertHash(m_acceptedCerts[i], m_acceptedSignatureAlgorithms[i], + m_digestAlgorithmFinder); + var reqID = m_acceptedReqIDs[i]; - var digestAlgorithm = m_digestAlgorithmFinder.Find(signatureAlgorithm) - ?? throw new CmpException("cannot find algorithm for digest from signature"); - - byte[] digest = DigestUtilities.CalculateDigest(digestAlgorithm.Algorithm, - cmpCertificate.GetEncoded(Asn1Encodable.Der)); - - v.Add(new CertStatus(digest, reqID)); + v.Add(new CertStatus(certHash, reqID)); } var content = CertConfirmContent.GetInstance(new DerSequence(v)); diff --git a/crypto/src/cmp/CertificateStatus.cs b/crypto/src/cmp/CertificateStatus.cs index 482e9f7f3..4c45a3cb8 100644 --- a/crypto/src/cmp/CertificateStatus.cs +++ b/crypto/src/cmp/CertificateStatus.cs @@ -1,11 +1,9 @@ using System; -using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cmp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; using Org.BouncyCastle.Operators.Utilities; -using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.X509; @@ -38,13 +36,9 @@ namespace Org.BouncyCastle.Cmp public virtual bool IsVerified(CmpCertificate cmpCertificate, AlgorithmIdentifier signatureAlgorithm) { - AlgorithmIdentifier digestAlgorithm = m_digestAlgorithmFinder.Find(signatureAlgorithm) - ?? throw new CmpException("cannot find algorithm for digest from signature"); + var certHash = CmpUtilities.CalculateCertHash(cmpCertificate, signatureAlgorithm, m_digestAlgorithmFinder); - byte[] digest = DigestUtilities.CalculateDigest(digestAlgorithm.Algorithm, - cmpCertificate.GetEncoded(Asn1Encodable.Der)); - - return Arrays.FixedTimeEquals(m_certStatus.CertHash.GetOctets(), digest); + return Arrays.FixedTimeEquals(m_certStatus.CertHash.GetOctets(), certHash); } } } diff --git a/crypto/src/cmp/CmpUtilities.cs b/crypto/src/cmp/CmpUtilities.cs new file mode 100644 index 000000000..d4e2c89bf --- /dev/null +++ b/crypto/src/cmp/CmpUtilities.cs @@ -0,0 +1,18 @@ +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.X509; +using Org.BouncyCastle.Operators.Utilities; + +namespace Org.BouncyCastle.Cmp +{ + internal static class CmpUtilities + { + internal static byte[] CalculateCertHash(Asn1Encodable asn1Encodable, AlgorithmIdentifier signatureAlgorithm, + IDigestAlgorithmFinder digestAlgorithmFinder) + { + var digestAlgorithm = digestAlgorithmFinder.Find(signatureAlgorithm) + ?? throw new CmpException("cannot find digest algorithm from signature algorithm"); + + return X509.X509Utilities.CalculateDigest(digestAlgorithm.Algorithm, asn1Encodable); + } + } +} diff --git a/crypto/src/crypto/operators/Asn1DigestFactory.cs b/crypto/src/crypto/operators/Asn1DigestFactory.cs index 0c1b6fb41..753047937 100644 --- a/crypto/src/crypto/operators/Asn1DigestFactory.cs +++ b/crypto/src/crypto/operators/Asn1DigestFactory.cs @@ -1,9 +1,5 @@ -using System; -using System.IO; - -using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Crypto.IO; using Org.BouncyCastle.Security; namespace Org.BouncyCastle.Crypto.Operators @@ -11,62 +7,24 @@ namespace Org.BouncyCastle.Crypto.Operators public class Asn1DigestFactory : IDigestFactory { - public static Asn1DigestFactory Get(DerObjectIdentifier oid) - { - return new Asn1DigestFactory(DigestUtilities.GetDigest(oid), oid); - } + public static Asn1DigestFactory Get(DerObjectIdentifier oid) => + new Asn1DigestFactory(DigestUtilities.GetDigest(oid), oid); - public static Asn1DigestFactory Get(string mechanism) - { - DerObjectIdentifier oid = DigestUtilities.GetObjectIdentifier(mechanism); - return new Asn1DigestFactory(DigestUtilities.GetDigest(oid), oid); - } + public static Asn1DigestFactory Get(string mechanism) => Get(DigestUtilities.GetObjectIdentifier(mechanism)); - private readonly IDigest mDigest; - private readonly DerObjectIdentifier mOid; + private readonly IDigest m_digest; + private readonly DerObjectIdentifier m_oid; public Asn1DigestFactory(IDigest digest, DerObjectIdentifier oid) { - this.mDigest = digest; - this.mOid = oid; - } - - public virtual object AlgorithmDetails - { - get { return new AlgorithmIdentifier(mOid); } + m_digest = digest; + m_oid = oid; } - public virtual int DigestLength - { - get { return mDigest.GetDigestSize(); } - } + public virtual object AlgorithmDetails => new AlgorithmIdentifier(m_oid); - public virtual IStreamCalculator CreateCalculator() - { - return new DfDigestStream(mDigest); - } - } - - internal class DfDigestStream - : IStreamCalculator - { - private readonly DigestSink mStream; - - public DfDigestStream(IDigest digest) - { - this.mStream = new DigestSink(digest); - } + public virtual int DigestLength => m_digest.GetDigestSize(); - public Stream Stream - { - get { return mStream; } - } - - public SimpleBlockResult GetResult() - { - byte[] result = new byte[mStream.Digest.GetDigestSize()]; - mStream.Digest.DoFinal(result, 0); - return new SimpleBlockResult(result); - } + public virtual IStreamCalculator CreateCalculator() => new DefaultDigestCalculator(m_digest); } } diff --git a/crypto/src/crypto/operators/DefaultDigestCalculator.cs b/crypto/src/crypto/operators/DefaultDigestCalculator.cs new file mode 100644 index 000000000..78ac30983 --- /dev/null +++ b/crypto/src/crypto/operators/DefaultDigestCalculator.cs @@ -0,0 +1,21 @@ +using System.IO; + +using Org.BouncyCastle.Crypto.IO; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public sealed class DefaultDigestCalculator + : IStreamCalculator + { + private readonly DigestSink m_digestSink; + + public DefaultDigestCalculator(IDigest digest) + { + m_digestSink = new DigestSink(digest); + } + + public Stream Stream => m_digestSink; + + public IBlockResult GetResult() => new DefaultDigestResult(m_digestSink.Digest); + } +} diff --git a/crypto/src/crypto/operators/DefaultDigestResult.cs b/crypto/src/crypto/operators/DefaultDigestResult.cs new file mode 100644 index 000000000..60625c421 --- /dev/null +++ b/crypto/src/crypto/operators/DefaultDigestResult.cs @@ -0,0 +1,27 @@ +using System; + +using Org.BouncyCastle.Security; + +namespace Org.BouncyCastle.Crypto.Operators +{ + public sealed class DefaultDigestResult + : IBlockResult + { + private readonly IDigest m_digest; + + public DefaultDigestResult(IDigest digest) + { + m_digest = digest; + } + + public byte[] Collect() => DigestUtilities.DoFinal(m_digest); + + public int Collect(byte[] buf, int off) => m_digest.DoFinal(buf, off); + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public int Collect(Span output) => m_digest.DoFinal(output); +#endif + + public int GetMaxResultLength() => m_digest.GetDigestSize(); + } +} diff --git a/crypto/src/x509/X509Utilities.cs b/crypto/src/x509/X509Utilities.cs index 45fa75916..5051b1b4e 100644 --- a/crypto/src/x509/X509Utilities.cs +++ b/crypto/src/x509/X509Utilities.cs @@ -10,6 +10,8 @@ using Org.BouncyCastle.Asn1.TeleTrust; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; @@ -127,6 +129,14 @@ namespace Org.BouncyCastle.X509 m_exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); } + internal static byte[] CalculateDigest(DerObjectIdentifier oid, Asn1Encodable asn1Encodable) + { + var digest = DigestUtilities.GetDigest(oid); + var digestCalculator = new DefaultDigestCalculator(digest); + var digestResult = CalculateResult(digestCalculator, asn1Encodable); + return digestResult.Collect(); + } + internal static TResult CalculateResult(IStreamCalculator streamCalculator, Asn1Encodable asn1Encodable) { @@ -195,6 +205,11 @@ namespace Org.BouncyCastle.X509 return CollectDerBitString(result); } + internal static DerBitString GenerateDigest(IDigestFactory digestFactory, Asn1Encodable asn1Encodable) + { + return GenerateBitString(digestFactory.CreateCalculator(), asn1Encodable); + } + internal static DerBitString GenerateMac(IMacFactory macFactory, Asn1Encodable asn1Encodable) { return GenerateBitString(macFactory.CreateCalculator(), asn1Encodable); -- cgit 1.4.1