From a4b91981f85f8daab5496344ea7e93f0de9b64b7 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Mon, 12 Dec 2016 12:05:53 -0800 Subject: [PATCH] Make TLS 1.3 check ECDSA KeyUsage and add test. Change-Id: Ibb5c5f6b945f72585f58c457158a386dfb4dae98 Reviewed-on: https://boringssl-review.googlesource.com/12710 Reviewed-by: Adam Langley Commit-Queue: Adam Langley CQ-Verified: CQ bot account: commit-bot@chromium.org --- ssl/test/runner/runner.go | 60 +++++++++++++++++++++++++++++++++++++++ ssl/tls13_both.c | 6 ++++ 2 files changed, 66 insertions(+) diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index a715ada0..fc66cf69 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -18,7 +18,9 @@ import ( "bytes" "crypto/ecdsa" "crypto/elliptic" + "crypto/rand" "crypto/x509" + "crypto/x509/pkix" "encoding/base64" "encoding/json" "encoding/pem" @@ -9794,6 +9796,63 @@ func addRetainOnlySHA256ClientCertTests() { } } +func addECDSAKeyUsageTests() { + p256 := elliptic.P256() + priv, err := ecdsa.GenerateKey(p256, rand.Reader) + if err != nil { + panic(err) + } + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + panic(err) + } + + template := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"Acme Co"}, + }, + NotBefore: time.Now(), + NotAfter: time.Now(), + + // An ECC certificate with only the keyAgreement key usgae may + // be used with ECDH, but not ECDSA. + KeyUsage: x509.KeyUsageKeyAgreement, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) + if err != nil { + panic(err) + } + + cert := Certificate{ + Certificate: [][]byte{derBytes}, + PrivateKey: priv, + } + + for _, ver := range tlsVersions { + if ver.version < VersionTLS12 { + continue + } + + testCases = append(testCases, testCase{ + testType: clientTest, + name: "ECDSAKeyUsage-" + ver.name, + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + Certificates: []Certificate{cert}, + }, + shouldFail: true, + expectedError: ":ECC_CERT_NOT_FOR_SIGNING:", + }) + } +} + func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { defer wg.Done() @@ -9919,6 +9978,7 @@ func main() { addRecordVersionTests() addCertificateTests() addRetainOnlySHA256ClientCertTests() + addECDSAKeyUsageTests() var wg sync.WaitGroup diff --git a/ssl/tls13_both.c b/ssl/tls13_both.c index 1be1897d..5a058b11 100644 --- a/ssl/tls13_both.c +++ b/ssl/tls13_both.c @@ -209,6 +209,12 @@ int tls13_process_certificate(SSL_HANDSHAKE *hs, int allow_anonymous) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto err; } + /* TLS 1.3 always uses certificate keys for signing thus the correct + * keyUsage is enforced. */ + if (!ssl_cert_check_digital_signature_key_usage(&certificate)) { + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + goto err; + } if (retain_sha256) { /* Retain the hash of the leaf certificate if requested. */