]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/x509: document AuthorityKeyId and don't mutate it.
authorAdam Langley <agl@golang.org>
Wed, 8 Feb 2017 17:28:53 +0000 (09:28 -0800)
committerAdam Langley <agl@golang.org>
Thu, 9 Feb 2017 18:33:41 +0000 (18:33 +0000)
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 <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/crypto/x509/x509.go

index 949ce0185615516f5bdbede356e5f9f5d84eb70d..efcef8187c726d7eb6b30c6b9aced789b8fdaacb 100644 (file)
@@ -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
        }