Commit 54bb4b9f authored by Paul van Brouwershaven's avatar Paul van Brouwershaven Committed by Adam Langley

crypto/x509: CertificateRequest signature verification

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/7371Reviewed-by: default avatarAdam Langley <agl@golang.org>
parent bff14175
...@@ -619,6 +619,12 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) { ...@@ -619,6 +619,12 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
// CheckSignature verifies that signature is a valid signature over signed from // CheckSignature verifies that signature is a valid signature over signed from
// c's public key. // c's public key.
func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) { 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 var hashType crypto.Hash
switch algo { switch algo {
...@@ -642,7 +648,7 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature ...@@ -642,7 +648,7 @@ func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature
h.Write(signed) h.Write(signed)
digest := h.Sum(nil) digest := h.Sum(nil)
switch pub := c.PublicKey.(type) { switch pub := publicKey.(type) {
case *rsa.PublicKey: case *rsa.PublicKey:
return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
case *dsa.PublicKey: case *dsa.PublicKey:
...@@ -1955,3 +1961,8 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error ...@@ -1955,3 +1961,8 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
return out, nil 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)
}
...@@ -904,6 +904,12 @@ func TestCreateCertificateRequest(t *testing.T) { ...@@ -904,6 +904,12 @@ func TestCreateCertificateRequest(t *testing.T) {
continue 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 { if out.Subject.CommonName != template.Subject.CommonName {
t.Errorf("%s: output subject common name and template subject common name don't match", test.name) 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) { } else if len(out.Subject.Organization) != len(template.Subject.Organization) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment