From aa027f072fe8f7871950cd256b2e04f12c1d4551 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 4 Apr 2023 21:20:26 +0700 Subject: X509: generation/validation of alternative signatures for certs and CRLs. --- crypto/src/x509/X509Crl.cs | 58 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 14 deletions(-) (limited to 'crypto/src/x509/X509Crl.cs') diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs index 81dd1c20e..1fc13a0a2 100644 --- a/crypto/src/x509/X509Crl.cs +++ b/crypto/src/x509/X509Crl.cs @@ -104,8 +104,7 @@ namespace Org.BouncyCastle.X509 : null; } - public virtual void Verify( - AsymmetricKeyParameter publicKey) + public virtual void Verify(AsymmetricKeyParameter publicKey) { Verify(new Asn1VerifierFactoryProvider(publicKey)); } @@ -116,26 +115,57 @@ namespace Org.BouncyCastle.X509 /// An appropriate provider for verifying the CRL's signature. /// True if the signature is valid. /// If verifier provider is not appropriate or the CRL algorithm is invalid. - public virtual void Verify( - IVerifierFactoryProvider verifierProvider) + public virtual void Verify(IVerifierFactoryProvider verifierProvider) { CheckSignature(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm)); } - protected virtual void CheckSignature( - IVerifierFactory verifier) + /// Verify the CRL's alternative signature using a verifier created using the passed in + /// verifier provider. + /// An appropriate provider for verifying the CRL's alternative signature. + /// + /// If verifier provider is not appropriate or the CRL alternative signature + /// algorithm is invalid. + public virtual void VerifyAltSignature(IVerifierFactoryProvider verifierProvider) { - // TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature - if (!c.SignatureAlgorithm.Equals(c.TbsCertList.Signature)) - throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList."); + var tbsCertList = c.TbsCertList; + var extensions = tbsCertList.Extensions; + + AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.FromExtensions(extensions); + AltSignatureValue altSigValue = AltSignatureValue.FromExtensions(extensions); + + var verifier = verifierProvider.CreateVerifierFactory(altSigAlg.Algorithm); + + Asn1Sequence tbsSeq = Asn1Sequence.GetInstance(tbsCertList.ToAsn1Object()); + Asn1EncodableVector v = new Asn1EncodableVector(); - IStreamCalculator streamCalculator = verifier.CreateCalculator(); - using (var stream = streamCalculator.Stream) + int start = 1; // want to skip signature field + if (tbsSeq[0] is DerInteger derInteger) + { + v.Add(derInteger); + start++; + } + + for (int i = start; i < tbsSeq.Count - 1; i++) { - c.TbsCertList.EncodeTo(stream, Asn1Encodable.Der); - } + v.Add(tbsSeq[i]); + } + + v.Add(X509Utilities.TrimExtensions(0, extensions)); + + if (!X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature)) + throw new InvalidKeyException("CRL alternative signature does not verify with supplied public key."); + } + + protected virtual void CheckSignature(IVerifierFactory verifier) + { + var tbsCertList = c.TbsCertList; + + // TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature + if (!c.SignatureAlgorithm.Equals(tbsCertList.Signature)) + throw new CrlException("Signature algorithm on CertificateList does not match TbsCertList."); - if (!streamCalculator.GetResult().IsVerified(GetSignature())) + if (!X509Utilities.VerifySignature(verifier, tbsCertList, c.Signature)) throw new InvalidKeyException("CRL does not verify with supplied public key."); } -- cgit 1.4.1