From dd150176c3cc49da68c8179f740eadc79404d351 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 3 Jul 2020 03:07:02 +0000 Subject: [PATCH] crypto/tls: create certs w/o KeyEncipherment KU for non-RSA keys in generate_cert.go Summary The crypto/tls/generate_cert.go utility should only set the template x509.Certificate's KeyUsage field to a value with the x509.KeyUsageKeyEncipherment bits set when the certificate subject public key is an RSA public key, not an ECDSA or ED25519 public key. Background RFC 5480 describes the usage of ECDSA elliptic curve subject keys with X.509. Unfortunately while Section 3 "Key Usages Bits" indicates which key usage bits MAY be used with a certificate that indicates id-ecPublicKey in the SubjectPublicKeyInfo field it doesn't provide guidance on which usages should *not* be included (e.g. the keyEncipherment bit, which is particular to RSA key exchange). The same problem is present in RFC 8410 Section 5 describing Key Usage Bits for ED25519 elliptic curve subject keys. There's an update to RFC 5480 in last call stage within the IETF LAMPS WG, draft-ietf-lamps-5480-ku-clarifications-00. This update is meant to clarify the allowed Key Usages extension values for certificates with ECDSA subject public keys by adding: > If the keyUsage extension is present in a certificate that indicates > id-ecPublicKey as algorithm of AlgorithmIdentifier [RFC2986] in > SubjectPublicKeyInfo, then following values MUST NOT be present: > > keyEncipherment; and > dataEncipherment. I don't believe there is an update for RFC 8410 in the works but I suspect it will be clarified similarly in the future. This commit updates generate_cert.go to ensure when the certificate public key is ECDSA or ED25519 the generated certificate has the x509.Certificate.KeyUsage field set to a value that doesn't include KUs specific to RSA. For ECDSA keys this will adhere to the updated RFC 5480 language. Fixes #36499 Change-Id: Ib1b0757c039b7fe97fc6d1e826fe6b88856c1964 GitHub-Last-Rev: a8f34fb33dde90e09b6f9a27b2598a82b3023abb GitHub-Pull-Request: golang/go#36500 Reviewed-on: https://go-review.googlesource.com/c/go/+/214337 Reviewed-by: Filippo Valsorda Run-TryBot: Filippo Valsorda TryBot-Result: Gobot Gobot --- src/crypto/tls/generate_cert.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/crypto/tls/generate_cert.go b/src/crypto/tls/generate_cert.go index f1d69c401abb84..1857185fe4d8f0 100644 --- a/src/crypto/tls/generate_cert.go +++ b/src/crypto/tls/generate_cert.go @@ -81,6 +81,16 @@ func main() { log.Fatalf("Failed to generate private key: %v", err) } + // ECDSA, ED25519 and RSA subject keys should have the DigitalSignature + // KeyUsage bits set in the x509.Certificate template + keyUsage := x509.KeyUsageDigitalSignature + // Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In + // the context of TLS this KeyUsage is particular to RSA key exchange and + // authentication. + if _, isRSA := priv.(*rsa.PrivateKey); isRSA { + keyUsage |= x509.KeyUsageKeyEncipherment + } + var notBefore time.Time if len(*validFrom) == 0 { notBefore = time.Now() @@ -107,7 +117,7 @@ func main() { NotBefore: notBefore, NotAfter: notAfter, - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + KeyUsage: keyUsage, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, }