From: Adam Langley Date: Wed, 8 Feb 2017 17:28:53 +0000 (-0800) Subject: crypto/x509: document AuthorityKeyId and don't mutate it. X-Git-Tag: go1.9beta1~1652 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=bfe7c81906212c69df754d5f4e3baa6413f092b3;p=gostls13.git crypto/x509: document AuthorityKeyId and don't mutate it. The AuthorityKeyId value from the template was used by CreateCertificate, but that wasn't documented. Also, CreateCertificate would stash a value in the template if it needed to override it, which was wrong: template should be read-only. Fixes #18962. Change-Id: Ida15c54c341e5bbf553756e8aa65021d8085f453 Reviewed-on: https://go-review.googlesource.com/36556 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go index 949ce01856..efcef8187c 100644 --- a/src/crypto/x509/x509.go +++ b/src/crypto/x509/x509.go @@ -1451,7 +1451,7 @@ func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP) (derBy return asn1.Marshal(rawValues) } -func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { +func buildExtensions(template *Certificate, authorityKeyId []byte) (ret []pkix.Extension, err error) { ret = make([]pkix.Extension, 10 /* maximum number of elements. */) n := 0 @@ -1525,9 +1525,9 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) { n++ } - if len(template.AuthorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) { + if len(authorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) { ret[n].Id = oidExtensionAuthorityKeyId - ret[n].Value, err = asn1.Marshal(authKeyId{template.AuthorityKeyId}) + ret[n].Value, err = asn1.Marshal(authKeyId{authorityKeyId}) if err != nil { return } @@ -1710,7 +1710,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori // following members of template are used: SerialNumber, Subject, NotBefore, // NotAfter, KeyUsage, ExtKeyUsage, UnknownExtKeyUsage, BasicConstraintsValid, // IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical, -// PermittedDNSDomains, SignatureAlgorithm. +// PermittedDNSDomains, SignatureAlgorithm, AuthorityKeyId. // // 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 @@ -1720,6 +1720,10 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori // // All keys types that are implemented via crypto.Signer are supported (This // includes *rsa.PublicKey and *ecdsa.PublicKey.) +// +// The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any, +// unless the resulting certificate is self-signed. Otherwise the value from +// template will be used. func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte, err error) { key, ok := priv.(crypto.Signer) if !ok { @@ -1750,11 +1754,12 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv return } + authorityKeyId := template.AuthorityKeyId if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 { - template.AuthorityKeyId = parent.SubjectKeyId + authorityKeyId = parent.SubjectKeyId } - extensions, err := buildExtensions(template) + extensions, err := buildExtensions(template, authorityKeyId) if err != nil { return }