From a375c08770711d4265a1606baae162c185ef916f Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 28 Jul 2023 20:13:02 +0700 Subject: Refactoring around digest calculation --- crypto/src/cmp/CertificateStatus.cs | 4 ++ crypto/src/cmp/CmpUtilities.cs | 2 +- crypto/src/cmp/GeneralPkiMessage.cs | 2 +- crypto/src/cmp/ProtectedPkiMessage.cs | 14 ++-- crypto/src/ocsp/CertificateID.cs | 97 ++++++++------------------ crypto/src/ocsp/RespID.cs | 52 +++++--------- crypto/src/x509/X509Utilities.cs | 16 +++-- crypto/src/x509/store/X509CertStoreSelector.cs | 11 ++- 8 files changed, 73 insertions(+), 125 deletions(-) diff --git a/crypto/src/cmp/CertificateStatus.cs b/crypto/src/cmp/CertificateStatus.cs index 4c45a3cb8..154992d10 100644 --- a/crypto/src/cmp/CertificateStatus.cs +++ b/crypto/src/cmp/CertificateStatus.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cmp; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Math; @@ -29,6 +30,9 @@ namespace Org.BouncyCastle.Cmp public virtual PkiStatusInfo StatusInfo => m_certStatus.StatusInfo; + public virtual DerInteger CertReqID => m_certStatus.CertReqID; + + [Obsolete("Use 'CertReqID' instead")] public virtual BigInteger CertRequestID => m_certStatus.CertReqID.Value; public virtual bool IsVerified(X509Certificate cert) => diff --git a/crypto/src/cmp/CmpUtilities.cs b/crypto/src/cmp/CmpUtilities.cs index d4e2c89bf..b1012d5b7 100644 --- a/crypto/src/cmp/CmpUtilities.cs +++ b/crypto/src/cmp/CmpUtilities.cs @@ -12,7 +12,7 @@ namespace Org.BouncyCastle.Cmp var digestAlgorithm = digestAlgorithmFinder.Find(signatureAlgorithm) ?? throw new CmpException("cannot find digest algorithm from signature algorithm"); - return X509.X509Utilities.CalculateDigest(digestAlgorithm.Algorithm, asn1Encodable); + return X509.X509Utilities.CalculateDigest(digestAlgorithm, asn1Encodable); } } } diff --git a/crypto/src/cmp/GeneralPkiMessage.cs b/crypto/src/cmp/GeneralPkiMessage.cs index d52161f6c..09c02434c 100644 --- a/crypto/src/cmp/GeneralPkiMessage.cs +++ b/crypto/src/cmp/GeneralPkiMessage.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Cmp /// PKI message. public GeneralPkiMessage(PkiMessage pkiMessage) { - this.m_pkiMessage = pkiMessage; + m_pkiMessage = pkiMessage; } /// diff --git a/crypto/src/cmp/ProtectedPkiMessage.cs b/crypto/src/cmp/ProtectedPkiMessage.cs index 9e442c426..dbce3c453 100644 --- a/crypto/src/cmp/ProtectedPkiMessage.cs +++ b/crypto/src/cmp/ProtectedPkiMessage.cs @@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Cmp public ProtectedPkiMessage(GeneralPkiMessage pkiMessage) { if (!pkiMessage.HasProtection) - throw new ArgumentException("GeneralPkiMessage not protected"); + throw new ArgumentException("GeneralPkiMessage not protected", nameof(pkiMessage)); m_pkiMessage = pkiMessage.ToAsn1Structure(); } @@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Cmp public ProtectedPkiMessage(PkiMessage pkiMessage) { if (null == pkiMessage.Header.ProtectionAlg) - throw new ArgumentException("PkiMessage not protected"); + throw new ArgumentException("PkiMessage not protected", nameof(pkiMessage)); m_pkiMessage = pkiMessage; } @@ -60,10 +60,8 @@ namespace Org.BouncyCastle.Cmp /// to verify the message if this method returns true. /// /// true if protection MAC PBE based, false otherwise. - public virtual bool HasPasswordBasedMacProtected - { - get { return CmpObjectIdentifiers.passwordBasedMac.Equals(Header.ProtectionAlg.Algorithm); } - } + public virtual bool HasPasswordBasedMacProtected => + CmpObjectIdentifiers.passwordBasedMac.Equals(ProtectionAlgorithm.Algorithm); /** * Return the message's protection algorithm. @@ -105,7 +103,7 @@ namespace Org.BouncyCastle.Cmp #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER return Verify(pkMacBuilder, password.AsSpan()); #else - var protectionAlgorithm = m_pkiMessage.Header.ProtectionAlg; + var protectionAlgorithm = ProtectionAlgorithm; if (!CmpObjectIdentifiers.passwordBasedMac.Equals(protectionAlgorithm.Algorithm)) throw new InvalidOperationException("protection algorithm is not mac based"); @@ -122,7 +120,7 @@ namespace Org.BouncyCastle.Cmp #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public virtual bool Verify(PKMacBuilder pkMacBuilder, ReadOnlySpan password) { - var protectionAlgorithm = m_pkiMessage.Header.ProtectionAlg; + var protectionAlgorithm = ProtectionAlgorithm; if (!CmpObjectIdentifiers.passwordBasedMac.Equals(protectionAlgorithm.Algorithm)) throw new InvalidOperationException("protection algorithm is not mac based"); diff --git a/crypto/src/ocsp/CertificateID.cs b/crypto/src/ocsp/CertificateID.cs index b972a0f66..72588b17f 100644 --- a/crypto/src/ocsp/CertificateID.cs +++ b/crypto/src/ocsp/CertificateID.cs @@ -3,26 +3,23 @@ using System; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Ocsp; using Org.BouncyCastle.Asn1.X509; -using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Ocsp { - public class CertificateID + public class CertificateID + : IEquatable { + // OiwObjectIdentifiers.IdSha1.Id public const string HashSha1 = "1.3.14.3.2.26"; - private readonly CertID id; + private readonly CertID m_id; - public CertificateID( - CertID id) + public CertificateID(CertID id) { - if (id == null) - throw new ArgumentNullException("id"); - - this.id = id; + m_id = id ?? throw new ArgumentNullException(nameof(id)); } /** @@ -30,71 +27,38 @@ namespace Org.BouncyCastle.Ocsp * certificate it signed. * @exception OcspException if any problems occur creating the id fields. */ - public CertificateID( - string hashAlgorithm, - X509Certificate issuerCert, - BigInteger serialNumber) + public CertificateID(string hashAlgorithm, X509Certificate issuerCert, BigInteger serialNumber) { AlgorithmIdentifier hashAlg = new AlgorithmIdentifier( new DerObjectIdentifier(hashAlgorithm), DerNull.Instance); - this.id = CreateCertID(hashAlg, issuerCert, new DerInteger(serialNumber)); + m_id = CreateCertID(hashAlg, issuerCert, new DerInteger(serialNumber)); } - public string HashAlgOid - { - get { return id.HashAlgorithm.Algorithm.Id; } - } + public string HashAlgOid => m_id.HashAlgorithm.Algorithm.Id; - public byte[] GetIssuerNameHash() - { - return id.IssuerNameHash.GetOctets(); - } + public byte[] GetIssuerNameHash() => m_id.IssuerNameHash.GetOctets(); - public byte[] GetIssuerKeyHash() - { - return id.IssuerKeyHash.GetOctets(); - } + public byte[] GetIssuerKeyHash() => m_id.IssuerKeyHash.GetOctets(); /** * return the serial number for the certificate associated * with this request. */ - public BigInteger SerialNumber - { - get { return id.SerialNumber.Value; } - } - - public bool MatchesIssuer( - X509Certificate issuerCert) - { - return CreateCertID(id.HashAlgorithm, issuerCert, id.SerialNumber).Equals(id); - } + public BigInteger SerialNumber => m_id.SerialNumber.Value; - public CertID ToAsn1Object() + public bool MatchesIssuer(X509Certificate issuerCert) { - return id; + return CreateCertID(m_id.HashAlgorithm, issuerCert, m_id.SerialNumber).Equals(m_id); } - public override bool Equals( - object obj) - { - if (obj == this) - return true; - - CertificateID other = obj as CertificateID; - - if (other == null) - return false; + public CertID ToAsn1Object() => m_id; - return id.ToAsn1Object().Equals(other.id.ToAsn1Object()); - } + public bool Equals(CertificateID other) => this == other || m_id.Equals(other?.m_id); - public override int GetHashCode() - { - return id.ToAsn1Object().GetHashCode(); - } + public override bool Equals(object obj) => Equals(obj as CertificateID); + public override int GetHashCode() => m_id.GetHashCode(); /** * Create a new CertificateID for a new serial number derived from a previous one @@ -107,29 +71,24 @@ namespace Org.BouncyCastle.Ocsp */ public static CertificateID DeriveCertificateID(CertificateID original, BigInteger newSerialNumber) { - return new CertificateID(new CertID(original.id.HashAlgorithm, original.id.IssuerNameHash, - original.id.IssuerKeyHash, new DerInteger(newSerialNumber))); + CertID originalID = original.ToAsn1Object(); + + return new CertificateID(new CertID(originalID.HashAlgorithm, originalID.IssuerNameHash, + originalID.IssuerKeyHash, new DerInteger(newSerialNumber))); } - private static CertID CreateCertID( - AlgorithmIdentifier hashAlg, - X509Certificate issuerCert, - DerInteger serialNumber) + private static CertID CreateCertID(AlgorithmIdentifier digestAlgorithm, X509Certificate issuerCert, + DerInteger serialNumber) { try { - string hashAlgorithm = hashAlg.Algorithm.Id; - X509Name issuerName = PrincipalUtilities.GetSubjectX509Principal(issuerCert); - byte[] issuerNameHash = DigestUtilities.CalculateDigest( - hashAlgorithm, issuerName.GetEncoded()); + byte[] issuerNameHash = X509Utilities.CalculateDigest(digestAlgorithm, issuerName); - AsymmetricKeyParameter issuerKey = issuerCert.GetPublicKey(); - SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerKey); - byte[] issuerKeyHash = DigestUtilities.CalculateDigest( - hashAlgorithm, info.PublicKey.GetBytes()); + byte[] issuerKey = issuerCert.CertificateStructure.SubjectPublicKeyInfo.PublicKey.GetBytes(); + byte[] issuerKeyHash = DigestUtilities.CalculateDigest(digestAlgorithm.Algorithm, issuerKey); - return new CertID(hashAlg, new DerOctetString(issuerNameHash), + return new CertID(digestAlgorithm, new DerOctetString(issuerNameHash), new DerOctetString(issuerKeyHash), serialNumber); } catch (Exception e) diff --git a/crypto/src/ocsp/RespID.cs b/crypto/src/ocsp/RespID.cs index 304b9cd49..fcd041a98 100644 --- a/crypto/src/ocsp/RespID.cs +++ b/crypto/src/ocsp/RespID.cs @@ -9,35 +9,33 @@ using Org.BouncyCastle.X509; namespace Org.BouncyCastle.Ocsp { - /** + /** * Carrier for a ResponderID. */ - public class RespID - { - internal readonly ResponderID id; + public class RespID + : IEquatable + { + private readonly ResponderID m_id; - public RespID( - ResponderID id) + public RespID(ResponderID id) { - this.id = id; + m_id = id ?? throw new ArgumentNullException(nameof(id)); } - public RespID( - X509Name name) + public RespID(X509Name name) { - this.id = new ResponderID(name); + m_id = new ResponderID(name); } - public RespID( - AsymmetricKeyParameter publicKey) + public RespID(AsymmetricKeyParameter publicKey) { try { SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey); + byte[] key = info.PublicKey.GetBytes(); + byte[] keyHash = DigestUtilities.CalculateDigest("SHA1", key); - byte[] keyHash = DigestUtilities.CalculateDigest("SHA1", info.PublicKey.GetBytes()); - - this.id = new ResponderID(new DerOctetString(keyHash)); + m_id = new ResponderID(new DerOctetString(keyHash)); } catch (Exception e) { @@ -45,28 +43,12 @@ namespace Org.BouncyCastle.Ocsp } } - public ResponderID ToAsn1Object() - { - return id; - } - - public override bool Equals( - object obj) - { - if (obj == this) - return true; + public ResponderID ToAsn1Object() => m_id; - RespID other = obj as RespID; + public bool Equals(RespID other) => this == other || m_id.Equals(other?.m_id); - if (other == null) - return false; + public override bool Equals(object obj) => Equals(obj as RespID); - return id.Equals(other.id); - } - - public override int GetHashCode() - { - return id.GetHashCode(); - } + public override int GetHashCode() => m_id.GetHashCode(); } } diff --git a/crypto/src/x509/X509Utilities.cs b/crypto/src/x509/X509Utilities.cs index 5051b1b4e..e7dfeb2c5 100644 --- a/crypto/src/x509/X509Utilities.cs +++ b/crypto/src/x509/X509Utilities.cs @@ -129,14 +129,22 @@ namespace Org.BouncyCastle.X509 m_exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); } - internal static byte[] CalculateDigest(DerObjectIdentifier oid, Asn1Encodable asn1Encodable) + internal static byte[] CalculateDigest(AlgorithmIdentifier digestAlgorithm, Asn1Encodable asn1Encodable) { - var digest = DigestUtilities.GetDigest(oid); + var digest = DigestUtilities.GetDigest(digestAlgorithm.Algorithm); var digestCalculator = new DefaultDigestCalculator(digest); var digestResult = CalculateResult(digestCalculator, asn1Encodable); return digestResult.Collect(); } + internal static byte[] CalculateDigest(IDigestFactory digestFactory, + Asn1Encodable asn1Encodable) + { + var digestCalculator = digestFactory.CreateCalculator(); + var digestResult = CalculateResult(digestCalculator, asn1Encodable); + return digestResult.Collect(); + } + internal static TResult CalculateResult(IStreamCalculator streamCalculator, Asn1Encodable asn1Encodable) { @@ -220,11 +228,11 @@ namespace Org.BouncyCastle.X509 return GenerateBitString(signatureFactory.CreateCalculator(), asn1Encodable); } - internal static bool VerifyMac(IMacFactory macFactory, Asn1Encodable asn1Encodable, DerBitString protection) + internal static bool VerifyMac(IMacFactory macFactory, Asn1Encodable asn1Encodable, DerBitString expected) { var result = CalculateResult(macFactory.CreateCalculator(), asn1Encodable); - return Arrays.FixedTimeEquals(result.Collect(), protection.GetBytes()); + return Arrays.FixedTimeEquals(result.Collect(), expected.GetOctets()); } internal static bool VerifySignature(IVerifierFactory verifierFactory, Asn1Encodable asn1Encodable, diff --git a/crypto/src/x509/store/X509CertStoreSelector.cs b/crypto/src/x509/store/X509CertStoreSelector.cs index ca15b9efa..c60c8b24b 100644 --- a/crypto/src/x509/store/X509CertStoreSelector.cs +++ b/crypto/src/x509/store/X509CertStoreSelector.cs @@ -276,11 +276,13 @@ namespace Org.BouncyCastle.X509.Store if (!MatchExtension(subjectKeyIdentifier, c, X509Extensions.SubjectKeyIdentifier)) return false; - if (subjectPublicKey != null && !subjectPublicKey.Equals(GetSubjectPublicKey(c))) + SubjectPublicKeyInfo subjectPublicKeyInfo = c.CertificateStructure.SubjectPublicKeyInfo; + + if (subjectPublicKey != null && !subjectPublicKey.Equals(subjectPublicKeyInfo)) return false; if (subjectPublicKeyAlgID != null - && !subjectPublicKeyAlgID.Equals(GetSubjectPublicKey(c).Algorithm)) + && !subjectPublicKeyAlgID.Equals(subjectPublicKeyInfo.Algorithm)) return false; return true; @@ -306,11 +308,6 @@ namespace Org.BouncyCastle.X509.Store return s == null ? null : new HashSet(s); } - private static SubjectPublicKeyInfo GetSubjectPublicKey(X509Certificate c) - { - return c.CertificateStructure.SubjectPublicKeyInfo; - } - private static bool MatchExtension(byte[] b, X509Certificate c, DerObjectIdentifier oid) { if (b == null) -- cgit 1.4.1