Check the server did not use a TLS 1.2 cipher suite pre-TLS 1.2. This check got refactored in OpenSSL 1.0.2 and broke in the process. Fix this and add a test. Otherwise things like client auth can get slightly confused; it will try to sign the MD5/SHA-1 hash, but the TLS 1.2 cipher suite may not use SSL_HANDSHAKE_MAC_DEFAULT, so those digests won't be available. Based on upstream's 226751ae4a1f3e00021c43399d7bb51a99c22c17. Change-Id: I5b864d3a696f3187b849c53b872c24fb7df27924 Reviewed-on: https://boringssl-review.googlesource.com/1696 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 97d1107..5f8c5db 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c
@@ -798,6 +798,7 @@ CBS server_hello, server_random, session_id; uint16_t server_version, cipher_suite; uint8_t compression_method; + unsigned long mask_ssl; n=s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, @@ -913,10 +914,16 @@ OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNKNOWN_CIPHER_RETURNED); goto f_err; } + /* ct->mask_ssl was computed from client capabilities. Now + * that the final version is known, compute a new mask_ssl. */ + if (!SSL_USE_TLS1_2_CIPHERS(s)) + mask_ssl = SSL_TLSV1_2; + else + mask_ssl = 0; /* If it is a disabled cipher we didn't send it in client hello, * so return an error. */ - if (c->algorithm_ssl & ct->mask_ssl || + if (c->algorithm_ssl & mask_ssl || c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) {
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index fa0e6d8..f22f95a 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go
@@ -445,6 +445,10 @@ // ClientKeyExchange message without the two-byte length // prefix, as if it were SSL3. SSL3RSAKeyExchange bool + + // SkipCipherVersionCheck causes the server to negotiate + // TLS 1.2 ciphers in earlier versions of TLS. + SkipCipherVersionCheck bool } func (c *Config) serverInit() {
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 855f992..6d61fd5 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go
@@ -832,7 +832,7 @@ if (candidate.flags&suiteECDSA != 0) != ecdsaOk { continue } - if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { + if !c.config.Bugs.SkipCipherVersionCheck && version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { continue } if c.isDTLS && candidate.flags&suiteNoDTLS != 0 {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index d238e8a..9322592 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go
@@ -483,6 +483,18 @@ shouldFail: true, expectedError: ":HTTPS_PROXY_REQUEST:", }, + { + name: "SkipCipherVersionCheck", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + MaxVersion: VersionTLS11, + Bugs: ProtocolBugs{ + SkipCipherVersionCheck: true, + }, + }, + shouldFail: true, + expectedError: ":WRONG_CIPHER_RETURNED:", + }, } func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int) error {