diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-04-05 12:22:26 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2023-04-05 12:22:26 +0700 |
commit | 2ba60e27a977781625f7e84360a9a6225a49cf28 (patch) | |
tree | 85e8d65fc407937a8fa67c1fdee475e0ff3dccf0 | |
parent | X509: generation/validation of alternative signatures for certs and CRLs. (diff) | |
download | BouncyCastle.NET-ed25519-2ba60e27a977781625f7e84360a9a6225a49cf28.tar.xz |
X509: Signature checks that return bool
-rw-r--r-- | crypto/src/x509/X509Certificate.cs | 68 | ||||
-rw-r--r-- | crypto/src/x509/X509Crl.cs | 80 | ||||
-rw-r--r-- | crypto/src/x509/X509V2AttributeCertificate.cs | 27 |
3 files changed, 115 insertions, 60 deletions
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs index 39df381df..c903811d4 100644 --- a/crypto/src/x509/X509Certificate.cs +++ b/crypto/src/x509/X509Certificate.cs @@ -632,6 +632,42 @@ namespace Org.BouncyCastle.X509 return buf.ToString(); } + public virtual bool IsSignatureValid(AsymmetricKeyParameter key) + { + return CheckSignatureValid(new Asn1VerifierFactory(c.SignatureAlgorithm, key)); + } + + public virtual bool IsSignatureValid(IVerifierFactoryProvider verifierProvider) + { + return CheckSignatureValid(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm)); + } + + public virtual bool IsAlternativeSignatureValid(IVerifierFactoryProvider verifierProvider) + { + var tbsCertificate = c.TbsCertificate; + var extensions = tbsCertificate.Extensions; + + AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.FromExtensions(extensions); + AltSignatureValue altSigValue = AltSignatureValue.FromExtensions(extensions); + + var verifier = verifierProvider.CreateVerifierFactory(altSigAlg.Algorithm); + + Asn1Sequence tbsSeq = Asn1Sequence.GetInstance(tbsCertificate.ToAsn1Object()); + Asn1EncodableVector v = new Asn1EncodableVector(); + + for (int i = 0; i < tbsSeq.Count - 1; i++) + { + if (i != 2) // signature field - must be ver 3 so version always present + { + v.Add(tbsSeq[i]); + } + } + + v.Add(X509Utilities.TrimExtensions(3, extensions)); + + return X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature); + } + /// <summary> /// Verify the certificate's signature using the nominated public key. /// </summary> @@ -662,40 +698,24 @@ namespace Org.BouncyCastle.X509 /// algorithm is invalid.</exception> public virtual void VerifyAltSignature(IVerifierFactoryProvider verifierProvider) { - var tbsCertificate = c.TbsCertificate; - var extensions = tbsCertificate.Extensions; - - AltSignatureAlgorithm altSigAlg = AltSignatureAlgorithm.FromExtensions(extensions); - AltSignatureValue altSigValue = AltSignatureValue.FromExtensions(extensions); - - var verifier = verifierProvider.CreateVerifierFactory(altSigAlg.Algorithm); - - Asn1Sequence tbsSeq = Asn1Sequence.GetInstance(tbsCertificate.ToAsn1Object()); - Asn1EncodableVector v = new Asn1EncodableVector(); - - for (int i = 0; i < tbsSeq.Count - 1; i++) - { - if (i != 2) // signature field - must be ver 3 so version always present - { - v.Add(tbsSeq[i]); - } - } - - v.Add(X509Utilities.TrimExtensions(3, extensions)); - - if (!X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature)) + if (!IsAlternativeSignatureValid(verifierProvider)) throw new InvalidKeyException("Public key presented not for certificate alternative signature"); } protected virtual void CheckSignature(IVerifierFactory verifier) { + if (!CheckSignatureValid(verifier)) + throw new InvalidKeyException("Public key presented not for certificate signature"); + } + + protected virtual bool CheckSignatureValid(IVerifierFactory verifier) + { var tbsCertificate = c.TbsCertificate; if (!IsAlgIDEqual(c.SignatureAlgorithm, tbsCertificate.Signature)) throw new CertificateException("signature algorithm in TBS cert not same as outer cert"); - if (!X509Utilities.VerifySignature(verifier, tbsCertificate, c.Signature)) - throw new InvalidKeyException("Public key presented not for certificate signature"); + return X509Utilities.VerifySignature(verifier, tbsCertificate, c.Signature); } private CachedEncoding GetCachedEncoding() diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs index 1fc13a0a2..5a1ce95e2 100644 --- a/crypto/src/x509/X509Crl.cs +++ b/crypto/src/x509/X509Crl.cs @@ -104,9 +104,49 @@ namespace Org.BouncyCastle.X509 : null; } + public virtual bool IsSignatureValid(AsymmetricKeyParameter key) + { + return CheckSignatureValid(new Asn1VerifierFactory(c.SignatureAlgorithm, key)); + } + + public virtual bool IsSignatureValid(IVerifierFactoryProvider verifierProvider) + { + return CheckSignatureValid(verifierProvider.CreateVerifierFactory(c.SignatureAlgorithm)); + } + + public virtual bool IsAlternativeSignatureValid(IVerifierFactoryProvider verifierProvider) + { + 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(); + + int start = 1; // want to skip signature field + if (tbsSeq[0] is DerInteger version) + { + v.Add(version); + start++; + } + + for (int i = start; i < tbsSeq.Count - 1; i++) + { + v.Add(tbsSeq[i]); + } + + v.Add(X509Utilities.TrimExtensions(0, extensions)); + + return X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature); + } + public virtual void Verify(AsymmetricKeyParameter publicKey) { - Verify(new Asn1VerifierFactoryProvider(publicKey)); + CheckSignature(new Asn1VerifierFactory(c.SignatureAlgorithm, publicKey)); } /// <summary> @@ -128,45 +168,25 @@ namespace Org.BouncyCastle.X509 /// algorithm is invalid.</exception> public virtual void VerifyAltSignature(IVerifierFactoryProvider verifierProvider) { - 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(); - - 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++) - { - v.Add(tbsSeq[i]); - } - - v.Add(X509Utilities.TrimExtensions(0, extensions)); - - if (!X509Utilities.VerifySignature(verifier, new DerSequence(v), altSigValue.Signature)) + if (!IsAlternativeSignatureValid(verifierProvider)) throw new InvalidKeyException("CRL alternative signature does not verify with supplied public key."); } protected virtual void CheckSignature(IVerifierFactory verifier) { - var tbsCertList = c.TbsCertList; + if (!CheckSignatureValid(verifier)) + throw new InvalidKeyException("CRL does not verify with supplied public key."); + } + + protected virtual bool CheckSignatureValid(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 (!X509Utilities.VerifySignature(verifier, tbsCertList, c.Signature)) - throw new InvalidKeyException("CRL does not verify with supplied public key."); + return X509Utilities.VerifySignature(verifier, tbsCertList, c.Signature); } public virtual int Version diff --git a/crypto/src/x509/X509V2AttributeCertificate.cs b/crypto/src/x509/X509V2AttributeCertificate.cs index 963f1ea4f..980b9f3d5 100644 --- a/crypto/src/x509/X509V2AttributeCertificate.cs +++ b/crypto/src/x509/X509V2AttributeCertificate.cs @@ -161,6 +161,16 @@ namespace Org.BouncyCastle.X509 return cert.GetSignatureOctets(); } + public virtual bool IsSignatureValid(AsymmetricKeyParameter key) + { + return CheckSignatureValid(new Asn1VerifierFactory(cert.SignatureAlgorithm, key)); + } + + public virtual bool IsSignatureValid(IVerifierFactoryProvider verifierProvider) + { + return CheckSignatureValid(verifierProvider.CreateVerifierFactory(cert.SignatureAlgorithm)); + } + public virtual void Verify(AsymmetricKeyParameter key) { CheckSignature(new Asn1VerifierFactory(cert.SignatureAlgorithm, key)); @@ -179,17 +189,22 @@ namespace Org.BouncyCastle.X509 protected virtual void CheckSignature(IVerifierFactory verifier) { - var acInfo = cert.ACInfo; + if (!CheckSignatureValid(verifier)) + throw new InvalidKeyException("Public key presented not for certificate signature"); + } + + protected virtual bool CheckSignatureValid(IVerifierFactory verifier) + { + var acInfo = cert.ACInfo; // TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature if (!cert.SignatureAlgorithm.Equals(acInfo.Signature)) - throw new CertificateException("Signature algorithm in certificate info not same as outer certificate"); + throw new CertificateException("Signature algorithm in certificate info not same as outer certificate"); - if (!X509Utilities.VerifySignature(verifier, acInfo, cert.SignatureValue)) - throw new InvalidKeyException("Public key presented not for certificate signature"); - } + return X509Utilities.VerifySignature(verifier, acInfo, cert.SignatureValue); + } - public virtual byte[] GetEncoded() + public virtual byte[] GetEncoded() { return cert.GetEncoded(); } |