mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
crypto/x509: check the private key passed to CreateCertificate
Unfortunately, we can't improve the function signature to refer to
crypto.PrivateKey and crypto.PublicKey, even if they are both
interface{}, because it would break assignments to function types.
Fixes #37845
Change-Id: I627f2ac1e1ba98b128dac5382f9cc2524eaef378
Reviewed-on: https://go-review.googlesource.com/c/go/+/224157
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
This commit is contained in:
parent
b38b1b2f9a
commit
ec4efa4208
1 changed files with 19 additions and 9 deletions
|
|
@ -1413,8 +1413,8 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori
|
||||||
// just an empty SEQUENCE.
|
// just an empty SEQUENCE.
|
||||||
var emptyASN1Subject = []byte{0x30, 0}
|
var emptyASN1Subject = []byte{0x30, 0}
|
||||||
|
|
||||||
// CreateCertificate creates a new X.509v3 certificate based on a template.
|
// CreateCertificate creates a new X.509 v3 certificate based on a template.
|
||||||
// The following members of template are used:
|
// The following members of template are currently used:
|
||||||
//
|
//
|
||||||
// - AuthorityKeyId
|
// - AuthorityKeyId
|
||||||
// - BasicConstraintsValid
|
// - BasicConstraintsValid
|
||||||
|
|
@ -1451,7 +1451,7 @@ var emptyASN1Subject = []byte{0x30, 0}
|
||||||
//
|
//
|
||||||
// The certificate is signed by parent. If parent is equal to template then the
|
// The certificate is signed by parent. If parent is equal to template then the
|
||||||
// certificate is self-signed. The parameter pub is the public key of the
|
// certificate is self-signed. The parameter pub is the public key of the
|
||||||
// signee and priv is the private key of the signer.
|
// certificate to be generated and priv is the private key of the signer.
|
||||||
//
|
//
|
||||||
// The returned slice is the certificate in DER encoding.
|
// The returned slice is the certificate in DER encoding.
|
||||||
//
|
//
|
||||||
|
|
@ -1465,7 +1465,7 @@ var emptyASN1Subject = []byte{0x30, 0}
|
||||||
//
|
//
|
||||||
// If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId
|
// If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId
|
||||||
// will be generated from the hash of the public key.
|
// will be generated from the hash of the public key.
|
||||||
func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte, err error) {
|
func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) ([]byte, error) {
|
||||||
key, ok := priv.(crypto.Signer)
|
key, ok := priv.(crypto.Signer)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
|
return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
|
||||||
|
|
@ -1491,12 +1491,12 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
|
||||||
|
|
||||||
asn1Issuer, err := subjectBytes(parent)
|
asn1Issuer, err := subjectBytes(parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
asn1Subject, err := subjectBytes(template)
|
asn1Subject, err := subjectBytes(template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
authorityKeyId := template.AuthorityKeyId
|
authorityKeyId := template.AuthorityKeyId
|
||||||
|
|
@ -1514,9 +1514,19 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
|
||||||
subjectKeyId = h[:]
|
subjectKeyId = h[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that the signer's public key matches the private key, if available.
|
||||||
|
type privateKey interface {
|
||||||
|
Equal(crypto.PublicKey) bool
|
||||||
|
}
|
||||||
|
if privPub, ok := key.Public().(privateKey); !ok {
|
||||||
|
return nil, errors.New("x509: internal error: supported public key does not implement Equal")
|
||||||
|
} else if parent.PublicKey != nil && !privPub.Equal(parent.PublicKey) {
|
||||||
|
return nil, errors.New("x509: provided PrivateKey doesn't match parent's PublicKey")
|
||||||
|
}
|
||||||
|
|
||||||
extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId)
|
extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
|
encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
|
||||||
|
|
@ -1533,7 +1543,7 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
|
||||||
|
|
||||||
tbsCertContents, err := asn1.Marshal(c)
|
tbsCertContents, err := asn1.Marshal(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
c.Raw = tbsCertContents
|
c.Raw = tbsCertContents
|
||||||
|
|
||||||
|
|
@ -1555,7 +1565,7 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv
|
||||||
var signature []byte
|
var signature []byte
|
||||||
signature, err = key.Sign(rand, signed, signerOpts)
|
signature, err = key.Sign(rand, signed, signerOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
signedCert, err := asn1.Marshal(certificate{
|
signedCert, err := asn1.Marshal(certificate{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue