]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: CertificateRequest signature verification
authorPaul van Brouwershaven <paul@vanbrouwershaven.com>
Wed, 11 Mar 2015 07:15:23 +0000 (08:15 +0100)
committerAdam Langley <agl@golang.org>
Sun, 26 Apr 2015 21:07:10 +0000 (21:07 +0000)
This implements a method for x509.CertificateRequest to prevent
certain attacks and to allow a CA/RA to properly check the validity
of the binding between an end entity and a key pair, to prove that
it has possession of (i.e., is able to use) the private key
corresponding to the public key for which a certificate is requested.

RFC 2986 section 3 states:

"A certification authority fulfills the request by authenticating the
requesting entity and verifying the entity's signature, and, if the
request is valid, constructing an X.509 certificate from the
distinguished name and public key, the issuer name, and the
certification authority's choice of serial number, validity period,
and signature algorithm."

Change-Id: I37795c3b1dfdfdd455d870e499b63885eb9bda4f
Reviewed-on: https://go-review.googlesource.com/7371
Reviewed-by: Adam Langley <agl@golang.org>
src/crypto/x509/x509.go
src/crypto/x509/x509_test.go

index 0c096e2b6f57892b903e4c03244b57dd1312fa37..71b0804d0ad880c0fabc75b78d679eab44832c03 100644 (file)
@@ -619,6 +619,12 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
 // CheckSignature verifies that signature is a valid signature over signed from
 // c's public key.
 func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) {
+       return checkSignature(algo, signed, signature, c.PublicKey)
+}
+
+// CheckSignature verifies that signature is a valid signature over signed from
+// a crypto.PublicKey.
+func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey) (err error) {
        var hashType crypto.Hash
 
        switch algo {
@@ -642,7 +648,7 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature
        h.Write(signed)
        digest := h.Sum(nil)
 
-       switch pub := c.PublicKey.(type) {
+       switch pub := publicKey.(type) {
        case *rsa.PublicKey:
                return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
        case *dsa.PublicKey:
@@ -1955,3 +1961,8 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
 
        return out, nil
 }
+
+// CheckSignature verifies that the signature on c is a valid signature
+func (c *CertificateRequest) CheckSignature() (err error) {
+       return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey)
+}
index 75207fe6194b24d1f7386c3efe060117d5eb32d0..95efaf33b51109156a303585133fd346693853df 100644 (file)
@@ -904,6 +904,12 @@ func TestCreateCertificateRequest(t *testing.T) {
                        continue
                }
 
+               err = out.CheckSignature()
+               if err != nil {
+                       t.Errorf("%s: failed to check certificate request signature: %s", test.name, err)
+                       continue
+               }
+
                if out.Subject.CommonName != template.Subject.CommonName {
                        t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
                } else if len(out.Subject.Organization) != len(template.Subject.Organization) {