Add TLS 1.3 record layer to go implementation. This implements the cipher suite constraints in "fake TLS 1.3". It also makes bssl_shim and runner enable it by default so we can start adding MaxVersion: VersionTLS12 markers to tests as 1.2 vs. 1.3 differences begin to take effect. Change-Id: If1caf6e43938c8d15b0a0f39f40963b8199dcef5 Reviewed-on: https://boringssl-review.googlesource.com/8340 Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/handshake_client.c b/ssl/handshake_client.c index 9b96bcd..2d49200 100644 --- a/ssl/handshake_client.c +++ b/ssl/handshake_client.c
@@ -591,6 +591,8 @@ (cipher->algorithm_auth & ssl->cert->mask_a)) { continue; } + /* TODO(davidben): Also check |SSL_CIPHER_get_max_version| against the + * minimum enabled version. See https://crbug.com/boringssl/66. */ if (SSL_CIPHER_get_min_version(cipher) > ssl3_version_from_wire(ssl, ssl->client_version)) { continue; @@ -864,7 +866,8 @@ /* If the cipher is disabled then we didn't sent it in the ClientHello, so if * the server selected it, it's an error. */ if ((c->algorithm_mkey & ct->mask_k) || (c->algorithm_auth & ct->mask_a) || - SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) { + SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) || + SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl)) { al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); goto f_err;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 43dcb02..9dab142 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c
@@ -293,7 +293,8 @@ ok = 1; /* Check the TLS version. */ - if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl)) { + if (SSL_CIPHER_get_min_version(c) > ssl3_protocol_version(ssl) || + SSL_CIPHER_get_max_version(c) < ssl3_protocol_version(ssl)) { ok = 0; }
diff --git a/ssl/ssl_cipher.c b/ssl/ssl_cipher.c index 539472d..3c4f325 100644 --- a/ssl/ssl_cipher.c +++ b/ssl/ssl_cipher.c
@@ -1727,6 +1727,15 @@ return SSL3_VERSION; } +uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mac == SSL_AEAD && + (cipher->algorithm_enc & SSL_CHACHA20POLY1305_OLD) == 0 && + (cipher->algorithm_mkey & SSL_kECDHE) != 0) { + return TLS1_3_VERSION; + } + return TLS1_2_VERSION; +} + /* return the actual cipher being used */ const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) { if (cipher != NULL) {
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index ef759d9..99a5b93 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc
@@ -752,6 +752,11 @@ return nullptr; } + if (!config->is_dtls) { + // Enable TLS 1.3 for tests. + SSL_CTX_set_max_version(ssl_ctx.get(), TLS1_3_VERSION); + } + std::string cipher_list = "ALL"; if (!config->cipher.empty()) { cipher_list = config->cipher;
diff --git a/ssl/test/runner/cipher_suites.go b/ssl/test/runner/cipher_suites.go index 26f51b0..8c5be3d 100644 --- a/ssl/test/runner/cipher_suites.go +++ b/ssl/test/runner/cipher_suites.go
@@ -52,8 +52,11 @@ // RSA based. suiteECDSA // suiteTLS12 indicates that the cipher suite should only be advertised - // and accepted when using TLS 1.2. + // and accepted when using TLS 1.2 or greater. suiteTLS12 + // suiteTLS13 indicates that the cipher suite can be used with TLS 1.3. + // Cipher suites lacking this flag may not be used with TLS 1.3. + suiteTLS13 // suiteSHA384 indicates that the cipher suite uses SHA384 as the // handshake hash. suiteSHA384 @@ -77,66 +80,89 @@ // the lengths, in bytes, of the key material needed for each component. keyLen int macLen int - ivLen int + ivLen func(version uint16) int ka func(version uint16) keyAgreement // flags is a bitmask of the suite* values, above. flags int cipher func(key, iv []byte, isRead bool) interface{} mac func(version uint16, macKey []byte) macFunction - aead func(key, fixedNonce []byte) *tlsAead + aead func(version uint16, key, fixedNonce []byte) *tlsAead } var cipherSuites = []*cipherSuite{ // Ciphersuite order is chosen so that ECDHE comes before plain RSA // and RC4 comes before AES (because of the Lucky13 attack). - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old}, - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, 0, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old}, - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteNoDTLS, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteNoDTLS, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, cipherAES, macSHA384, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, cipherAES, macSHA384, nil}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, - {TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, cecpq1RSAKA, suiteCECPQ1 | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, - {TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, cecpq1ECDSAKA, suiteCECPQ1 | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, - {TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, cecpq1RSAKA, suiteCECPQ1 | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, cecpq1ECDSAKA, suiteCECPQ1 | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, dheRSAKA, suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, dheRSAKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, dheRSAKA, suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 32, 32, 16, dheRSAKA, suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, dheRSAKA, 0, cipherAES, macSHA1, nil}, - {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, dheRSAKA, 0, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteNoDTLS, cipherRC4, macSHA1, nil}, - {TLS_RSA_WITH_RC4_128_MD5, 16, 16, 0, rsaKA, suiteNoDTLS, cipherRC4, macMD5, nil}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_RSA_WITH_AES_256_CBC_SHA256, 32, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, - {TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, dheRSAKA, 0, cipher3DES, macSHA1, nil}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, - {TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, - {TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, - {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, - {TLS_PSK_WITH_RC4_128_SHA, 16, 20, 0, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil}, - {TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil}, - {TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_NULL_SHA, 0, 20, 0, rsaKA, suiteNoDTLS, cipherNull, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteTLS13, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteTLS13, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, noIV, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old}, + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD, 32, 0, noIV, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadCHACHA20POLY1305Old}, + {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM}, + {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM}, + {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, noIV, ecdheRSAKA, suiteECDHE | suiteNoDTLS, cipherRC4, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, noIV, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteNoDTLS, cipherRC4, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, cipherAES, macSHA256, nil}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 32, 48, ivLenAES, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, cipherAES, macSHA384, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 32, 48, ivLenAES, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, cipherAES, macSHA384, nil}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, + {TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, cecpq1RSAKA, suiteCECPQ1 | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, + {TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, cecpq1ECDSAKA, suiteCECPQ1 | suiteECDSA | suiteTLS12, nil, nil, aeadCHACHA20POLY1305}, + {TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, cecpq1RSAKA, suiteCECPQ1 | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, cecpq1ECDSAKA, suiteCECPQ1 | suiteECDSA | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, dheRSAKA, suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM}, + {TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, dheRSAKA, suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, dheRSAKA, suiteTLS12, cipherAES, macSHA256, nil}, + {TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, 32, 32, ivLenAES, dheRSAKA, suiteTLS12, cipherAES, macSHA256, nil}, + {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, dheRSAKA, 0, cipherAES, macSHA1, nil}, + {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, dheRSAKA, 0, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, rsaKA, suiteTLS12, nil, nil, aeadAESGCM}, + {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_RSA_WITH_RC4_128_SHA, 16, 20, noIV, rsaKA, suiteNoDTLS, cipherRC4, macSHA1, nil}, + {TLS_RSA_WITH_RC4_128_MD5, 16, 16, noIV, rsaKA, suiteNoDTLS, cipherRC4, macMD5, nil}, + {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, ivLenAES, rsaKA, suiteTLS12, cipherAES, macSHA256, nil}, + {TLS_RSA_WITH_AES_256_CBC_SHA256, 32, 32, ivLenAES, rsaKA, suiteTLS12, cipherAES, macSHA256, nil}, + {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, rsaKA, 0, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, rsaKA, 0, cipherAES, macSHA1, nil}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, ivLen3DES, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, + {TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, ivLen3DES, dheRSAKA, 0, cipher3DES, macSHA1, nil}, + {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, ivLen3DES, rsaKA, 0, cipher3DES, macSHA1, nil}, + {TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, 32, 0, ivLenChaCha20Poly1305, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteTLS13, nil, nil, aeadCHACHA20POLY1305}, + {TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, 16, 0, ivLenAESGCM, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteTLS13, nil, nil, aeadAESGCM}, + {TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384, 32, 0, ivLenAESGCM, ecdhePSKKA, suiteECDHE | suitePSK | suiteTLS12 | suiteTLS13 | suiteSHA384, nil, nil, aeadAESGCM}, + {TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, + {TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil}, + {TLS_PSK_WITH_RC4_128_SHA, 16, 20, noIV, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil}, + {TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, ivLenAES, pskKA, suitePSK, cipherAES, macSHA1, nil}, + {TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, ivLenAES, pskKA, suitePSK, cipherAES, macSHA1, nil}, + {TLS_RSA_WITH_NULL_SHA, 0, 20, noIV, rsaKA, suiteNoDTLS, cipherNull, macSHA1, nil}, +} + +func noIV(vers uint16) int { + return 0 +} + +func ivLenChaCha20Poly1305(vers uint16) int { + return 12 +} + +func ivLenAESGCM(vers uint16) int { + if vers >= VersionTLS13 { + return 12 + } + return 4 +} + +func ivLenAES(vers uint16) int { + return 16 +} + +func ivLen3DES(vers uint16) int { + return 8 } type nullCipher struct{} @@ -243,7 +269,7 @@ return f.aead.Open(out, f.openNonce, plaintext, additionalData) } -func aeadAESGCM(key, fixedNonce []byte) *tlsAead { +func aeadAESGCM(version uint16, key, fixedNonce []byte) *tlsAead { aes, err := aes.NewCipher(key) if err != nil { panic(err) @@ -257,10 +283,14 @@ copy(nonce1, fixedNonce) copy(nonce2, fixedNonce) + if version >= VersionTLS13 { + return &tlsAead{&xorNonceAEAD{nonce1, nonce2, aead}, false} + } + return &tlsAead{&fixedNonceAEAD{nonce1, nonce2, aead}, true} } -func aeadCHACHA20POLY1305Old(key, fixedNonce []byte) *tlsAead { +func aeadCHACHA20POLY1305Old(version uint16, key, fixedNonce []byte) *tlsAead { aead, err := newChaCha20Poly1305Old(key) if err != nil { panic(err) @@ -301,7 +331,7 @@ return ret, err } -func aeadCHACHA20POLY1305(key, fixedNonce []byte) *tlsAead { +func aeadCHACHA20POLY1305(version uint16, key, fixedNonce []byte) *tlsAead { aead, err := newChaCha20Poly1305(key) if err != nil { panic(err)
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index 6ff8bac..ae03850 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go
@@ -23,6 +23,7 @@ VersionTLS10 = 0x0301 VersionTLS11 = 0x0302 VersionTLS12 = 0x0303 + VersionTLS13 = 0x0304 ) const ( @@ -33,7 +34,7 @@ maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) minVersion = VersionSSL30 - maxVersion = VersionTLS12 + maxVersion = VersionTLS13 ) // TLS record types.
diff --git a/ssl/test/runner/conn.go b/ssl/test/runner/conn.go index 3913995..3f406bb 100644 --- a/ssl/test/runner/conn.go +++ b/ssl/test/runner/conn.go
@@ -345,8 +345,9 @@ // decrypt checks and strips the mac and decrypts the data in b. Returns a // success boolean, the number of bytes to skip from the start of the record in -// order to get the application payload, and an optional alert value. -func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) { +// order to get the application payload, the encrypted record type (or 0 +// if there is none), and an optional alert value. +func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, contentType recordType, alertValue alert) { recordHeaderLen := hc.recordHeaderLen() // pull out payload @@ -376,22 +377,37 @@ if c.explicitNonce { explicitIVLen = 8 if len(payload) < explicitIVLen { - return false, 0, alertBadRecordMAC + return false, 0, 0, alertBadRecordMAC } nonce = payload[:8] payload = payload[8:] } - var additionalData [13]byte - copy(additionalData[:], seq) - copy(additionalData[8:], b.data[:3]) - n := len(payload) - c.Overhead() - additionalData[11] = byte(n >> 8) - additionalData[12] = byte(n) + var additionalData []byte + if hc.version < VersionTLS13 { + additionalData = make([]byte, 13) + copy(additionalData, seq) + copy(additionalData[8:], b.data[:3]) + n := len(payload) - c.Overhead() + additionalData[11] = byte(n >> 8) + additionalData[12] = byte(n) + } var err error - payload, err = c.Open(payload[:0], nonce, payload, additionalData[:]) + payload, err = c.Open(payload[:0], nonce, payload, additionalData) if err != nil { - return false, 0, alertBadRecordMAC + return false, 0, 0, alertBadRecordMAC + } + if hc.version >= VersionTLS13 { + i := len(payload) + for i > 0 && payload[i-1] == 0 { + i-- + } + payload = payload[:i] + if len(payload) == 0 { + return false, 0, 0, alertUnexpectedMessage + } + contentType = recordType(payload[len(payload)-1]) + payload = payload[:len(payload)-1] } b.resize(recordHeaderLen + explicitIVLen + len(payload)) case cbcMode: @@ -401,7 +417,7 @@ } if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) { - return false, 0, alertBadRecordMAC + return false, 0, 0, alertBadRecordMAC } if explicitIVLen > 0 { @@ -436,7 +452,7 @@ // check, strip mac if hc.mac != nil { if len(payload) < macSize { - return false, 0, alertBadRecordMAC + return false, 0, 0, alertBadRecordMAC } // strip mac off payload, b.data @@ -448,13 +464,13 @@ localMAC := hc.mac.MAC(hc.inDigestBuf, seq, b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], payload[:n]) if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { - return false, 0, alertBadRecordMAC + return false, 0, 0, alertBadRecordMAC } hc.inDigestBuf = localMAC } hc.incSeq(false) - return true, recordHeaderLen + explicitIVLen, 0 + return true, recordHeaderLen + explicitIVLen, contentType, 0 } // padToBlockSize calculates the needed padding block, if any, for a payload. @@ -486,7 +502,7 @@ } // encrypt encrypts and macs the data in b. -func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { +func (hc *halfConn) encrypt(b *block, explicitIVLen int, typ recordType) (bool, alert) { recordHeaderLen := hc.recordHeaderLen() // mac @@ -507,8 +523,18 @@ case cipher.Stream: c.XORKeyStream(payload, payload) case *tlsAead: + contentTypeLen := 0 + if hc.version >= VersionTLS13 { + contentTypeLen = 1 + } payloadLen := len(b.data) - recordHeaderLen - explicitIVLen - b.resize(len(b.data) + c.Overhead()) + b.resize(len(b.data) + contentTypeLen + c.Overhead()) + if hc.version >= VersionTLS13 { + b.data[payloadLen+recordHeaderLen] = byte(typ) + payloadLen += 1 + // TODO(nharper): Add ProtocolBugs to add + // padding. + } nonce := hc.outSeq[:] if c.explicitNonce { nonce = b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] @@ -516,13 +542,16 @@ payload := b.data[recordHeaderLen+explicitIVLen:] payload = payload[:payloadLen] - var additionalData [13]byte - copy(additionalData[:], hc.outSeq[:]) - copy(additionalData[8:], b.data[:3]) - additionalData[11] = byte(payloadLen >> 8) - additionalData[12] = byte(payloadLen) + var additionalData []byte + if hc.version < VersionTLS13 { + additionalData = make([]byte, 13) + copy(additionalData, hc.outSeq[:]) + copy(additionalData[8:], b.data[:3]) + additionalData[11] = byte(payloadLen >> 8) + additionalData[12] = byte(payloadLen) + } - c.Seal(payload[:0], nonce, payload, additionalData[:]) + c.Seal(payload[:0], nonce, payload, additionalData) case cbcMode: blockSize := c.BlockSize() if explicitIVLen > 0 { @@ -686,7 +715,7 @@ vers := uint16(b.data[1])<<8 | uint16(b.data[2]) n := int(b.data[3])<<8 | int(b.data[4]) if c.haveVers { - if vers != c.vers { + if vers != c.vers && c.vers < VersionTLS13 { c.sendAlert(alertProtocolVersion) return 0, nil, c.in.setErrorLocked(fmt.Errorf("tls: received record with version %x when expecting version %x", vers, c.vers)) } @@ -726,7 +755,12 @@ // Process message. b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n) - ok, off, err := c.in.decrypt(b) + ok, off, encTyp, err := c.in.decrypt(b) + if c.vers >= VersionTLS13 && c.in.cipher != nil { + // TODO(nharper): Check that outer type (typ) is + // application data. + typ = encTyp + } if !ok { c.in.setErrorLocked(c.sendAlert(err)) } @@ -931,10 +965,17 @@ } b.resize(recordHeaderLen + explicitIVLen + m) b.data[0] = byte(typ) + if c.vers >= VersionTLS13 && c.out.cipher != nil { + // TODO(nharper): Add a ProtocolBugs to skip this. + b.data[0] = byte(recordTypeApplicationData) + } vers := c.vers - if vers == 0 { + if vers == 0 || vers >= VersionTLS13 { // Some TLS servers fail if the record version is // greater than TLS 1.0 for the initial ClientHello. + // + // TLS 1.3 fixes the version number in the record + // layer to {3, 1}. vers = VersionTLS10 } b.data[1] = byte(vers >> 8) @@ -952,7 +993,7 @@ } } copy(b.data[recordHeaderLen+explicitIVLen:], data) - c.out.encrypt(b, explicitIVLen) + c.out.encrypt(b, explicitIVLen, typ) _, err = c.conn.Write(b.data) if err != nil { break
diff --git a/ssl/test/runner/dtls.go b/ssl/test/runner/dtls.go index a31dfc0..3623c55 100644 --- a/ssl/test/runner/dtls.go +++ b/ssl/test/runner/dtls.go
@@ -105,7 +105,9 @@ // Process message. b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n) - ok, off, err := c.in.decrypt(b) + // TODO(nharper): Once DTLS 1.3 is defined, handle the extra + // parameter from decrypt. + ok, off, _, err := c.in.decrypt(b) if !ok { c.in.setErrorLocked(c.sendAlert(err)) } @@ -302,6 +304,8 @@ panic("Unknown cipher") } b.resize(recordHeaderLen + explicitIVLen + len(data)) + // TODO(nharper): DTLS 1.3 will likely need to set this to + // recordTypeApplicationData if c.out.cipher != nil. b.data[0] = byte(typ) vers := c.vers if vers == 0 { @@ -327,7 +331,7 @@ } } copy(b.data[recordHeaderLen+explicitIVLen:], data) - c.out.encrypt(b, explicitIVLen) + c.out.encrypt(b, explicitIVLen, typ) return }
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go index 76118b3..5123f55 100644 --- a/ssl/test/runner/handshake_client.go +++ b/ssl/test/runner/handshake_client.go
@@ -670,7 +670,7 @@ c := hs.c clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) + keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen(c.vers)) var clientCipher, serverCipher interface{} var clientHash, serverHash macFunction if hs.suite.cipher != nil { @@ -679,8 +679,8 @@ serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) serverHash = hs.suite.mac(c.vers, serverMAC) } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) + clientCipher = hs.suite.aead(c.vers, clientKey, clientIV) + serverCipher = hs.suite.aead(c.vers, serverKey, serverIV) } c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index cf5701f..7d462b5 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go
@@ -779,7 +779,7 @@ c := hs.c clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) + keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen(c.vers)) var clientCipher, serverCipher interface{} var clientHash, serverHash macFunction @@ -790,8 +790,8 @@ serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) serverHash = hs.suite.mac(c.vers, serverMAC) } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) + clientCipher = hs.suite.aead(c.vers, clientKey, clientIV) + serverCipher = hs.suite.aead(c.vers, serverKey, serverIV) } c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
diff --git a/ssl/test/runner/prf.go b/ssl/test/runner/prf.go index f1b26de..1bfe84c 100644 --- a/ssl/test/runner/prf.go +++ b/ssl/test/runner/prf.go
@@ -130,7 +130,11 @@ return prf30 case VersionTLS10, VersionTLS11: return prf10 - case VersionTLS12: + // TODO(nharper): VersionTLS13 is in the case statement below only to + // support Fake TLS 1.3. Real TLS 1.3 should never call this function. + // Once we no longer support Fake TLS 1.3, the VersionTLS13 should be + // removed from this case statement. + case VersionTLS12, VersionTLS13: if suite.flags&suiteSHA384 != 0 { return prf12(sha512.New384) }
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 17e03cb..e6bfba4 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go
@@ -883,6 +883,8 @@ {"TLS1", VersionTLS10, "-no-tls1", true}, {"TLS11", VersionTLS11, "-no-tls11", false}, {"TLS12", VersionTLS12, "-no-tls12", true}, + // TODO(nharper): Once we have a real implementation of TLS 1.3, update the name here. + {"FakeTLS13", VersionTLS13, "-no-tls13", false}, } var testCipherSuites = []struct { @@ -948,6 +950,10 @@ hasComponent(suiteName, "POLY1305") } +func isTLS13Suite(suiteName string) bool { + return (hasComponent(suiteName, "GCM") || hasComponent(suiteName, "POLY1305")) && hasComponent(suiteName, "ECDHE") && !hasComponent(suiteName, "OLD") +} + func isDTLSCipher(suiteName string) bool { return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL") } @@ -1310,7 +1316,7 @@ FragmentClientVersion: true, }, }, - expectedVersion: VersionTLS12, + expectedVersion: VersionTLS13, }, { testType: serverTest, @@ -1320,7 +1326,7 @@ SendClientVersion: 0x03ff, }, }, - expectedVersion: VersionTLS12, + expectedVersion: VersionTLS13, }, { testType: serverTest, @@ -1330,7 +1336,7 @@ SendClientVersion: 0x0400, }, }, - expectedVersion: VersionTLS12, + expectedVersion: VersionTLS13, }, { testType: serverTest, @@ -1388,6 +1394,7 @@ { name: "RSAEphemeralKey", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ RSAEphemeralKey: true, @@ -1657,6 +1664,7 @@ { name: "FalseStart-SkipServerSecondLeg", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -1678,6 +1686,7 @@ { name: "FalseStart-SkipServerSecondLeg-Implicit", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -1841,6 +1850,7 @@ { name: "FalseStart-BadFinished", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -1860,6 +1870,7 @@ { name: "NoFalseStart-NoALPN", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ ExpectFalseStart: true, @@ -1877,6 +1888,7 @@ { name: "NoFalseStart-NoAEAD", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -1896,6 +1908,7 @@ { name: "NoFalseStart-RSA", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -1915,6 +1928,7 @@ { name: "NoFalseStart-DHE_RSA", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -1947,6 +1961,7 @@ testType: serverTest, name: "NoCommonCurves", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, @@ -2301,6 +2316,10 @@ shouldClientFail = true shouldServerFail = true } + if !isTLS13Suite(suite.name) && ver.version == VersionTLS13 { + shouldClientFail = true + shouldServerFail = true + } if !isDTLSCipher(suite.name) && protocol == dtls { shouldClientFail = true shouldServerFail = true @@ -2360,40 +2379,31 @@ shouldFail: shouldClientFail, expectedError: expectedClientError, }) - } - } - // Ensure both TLS and DTLS accept their maximum record sizes. - testCases = append(testCases, testCase{ - name: suite.name + "-LargeRecord", - config: Config{ - CipherSuites: []uint16{suite.id}, - Certificates: []Certificate{cert}, - PreSharedKey: []byte(psk), - PreSharedKeyIdentity: pskIdentity, - }, - flags: flags, - messageLen: maxPlaintext, - }) - if isDTLSCipher(suite.name) { - testCases = append(testCases, testCase{ - protocol: dtls, - name: suite.name + "-LargeRecord-DTLS", - config: Config{ - CipherSuites: []uint16{suite.id}, - Certificates: []Certificate{cert}, - PreSharedKey: []byte(psk), - PreSharedKeyIdentity: pskIdentity, - }, - flags: flags, - messageLen: maxPlaintext, - }) + if !shouldClientFail { + // Ensure the maximum record size is accepted. + testCases = append(testCases, testCase{ + name: prefix + ver.name + "-" + suite.name + "-LargeRecord", + config: Config{ + MinVersion: ver.version, + MaxVersion: ver.version, + CipherSuites: []uint16{suite.id}, + Certificates: []Certificate{cert}, + PreSharedKey: []byte(psk), + PreSharedKeyIdentity: pskIdentity, + }, + flags: flags, + messageLen: maxPlaintext, + }) + } + } } } testCases = append(testCases, testCase{ name: "WeakDH", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ // This is a 1023-bit prime number, generated @@ -2409,6 +2419,7 @@ testCases = append(testCases, testCase{ name: "SillyDH", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ // This is a 4097-bit prime number, generated @@ -2428,6 +2439,7 @@ testType: serverTest, name: "DHPublicValuePadded", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ RequireDHPublicValueLen: (1025 + 7) / 8, @@ -2559,6 +2571,7 @@ testCases = append(testCases, testCase{ name: "MaxCBCPadding", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ MaxPadding: true, @@ -2569,6 +2582,7 @@ testCases = append(testCases, testCase{ name: "BadCBCPadding", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ PaddingFirstByteBad: true, @@ -2582,6 +2596,7 @@ testCases = append(testCases, testCase{ name: "BadCBCPadding255", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, Bugs: ProtocolBugs{ MaxPadding: true, @@ -2690,9 +2705,15 @@ } } + // TODO(davidben): These tests will need TLS 1.3 versions when the + // handshake is separate. + testCases = append(testCases, testCase{ - testType: serverTest, - name: "RequireAnyClientCertificate", + testType: serverTest, + name: "RequireAnyClientCertificate", + config: Config{ + MaxVersion: VersionTLS12, + }, flags: []string{"-require-any-client-certificate"}, shouldFail: true, expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", @@ -2713,6 +2734,7 @@ testType: serverTest, name: "SkipClientCertificate", config: Config{ + MaxVersion: VersionTLS12, Bugs: ProtocolBugs{ SkipClientCertificate: true, }, @@ -2728,6 +2750,7 @@ testType: clientTest, name: "ClientAuth-PSK", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, PreSharedKey: []byte("secret"), ClientAuth: RequireAnyClientCert, @@ -2744,6 +2767,7 @@ testType: clientTest, name: "ClientAuth-ECDHE_PSK", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, PreSharedKey: []byte("secret"), ClientAuth: RequireAnyClientCert, @@ -2895,6 +2919,9 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) { var tests []testCase + // TODO(davidben): These tests will need both TLS 1.2 and TLS 1.3 + // versions when the handshake becomes completely different. + // Basic handshake, with resumption. Client and server, // session ID and session ticket. tests = append(tests, testCase{ @@ -3038,6 +3065,7 @@ testType: serverTest, name: "Basic-Server-RSA", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, }, flags: []string{ @@ -3049,6 +3077,7 @@ testType: serverTest, name: "Basic-Server-ECDHE-RSA", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, flags: []string{ @@ -3060,6 +3089,7 @@ testType: serverTest, name: "Basic-Server-ECDHE-ECDSA", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, }, flags: []string{ @@ -3097,6 +3127,7 @@ tests = append(tests, testCase{ name: "EmptyPSKHint-Client", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, PreSharedKey: []byte("secret"), }, @@ -3106,6 +3137,7 @@ testType: serverTest, name: "EmptyPSKHint-Server", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, PreSharedKey: []byte("secret"), }, @@ -3204,6 +3236,7 @@ tests = append(tests, testCase{ name: "FalseStart", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -3222,6 +3255,7 @@ tests = append(tests, testCase{ name: "FalseStart-ALPN", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, Bugs: ProtocolBugs{ @@ -3241,6 +3275,7 @@ tests = append(tests, testCase{ name: "FalseStart-Implicit", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, }, @@ -3255,6 +3290,7 @@ tests = append(tests, testCase{ name: "FalseStart-SessionTicketsDisabled", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, SessionTicketsDisabled: true, @@ -3277,6 +3313,7 @@ // Choose a cipher suite that does not involve // elliptic curves, so no extensions are // involved. + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, Bugs: ProtocolBugs{ SendV2ClientHello: true, @@ -3467,6 +3504,10 @@ if clientVers > VersionTLS10 { clientVers = VersionTLS10 } + serverVers := expectedVersion + if expectedVersion >= VersionTLS13 { + serverVers = VersionTLS10 + } testCases = append(testCases, testCase{ protocol: protocol, testType: clientTest, @@ -3501,7 +3542,7 @@ config: Config{ MaxVersion: runnerVers.version, Bugs: ProtocolBugs{ - ExpectInitialRecordVersion: expectedVersion, + ExpectInitialRecordVersion: serverVers, }, }, flags: flags, @@ -3514,7 +3555,7 @@ config: Config{ MaxVersion: runnerVers.version, Bugs: ProtocolBugs{ - ExpectInitialRecordVersion: expectedVersion, + ExpectInitialRecordVersion: serverVers, }, }, flags: []string{"-max-version", shimVersFlag}, @@ -4062,6 +4103,17 @@ func addResumptionVersionTests() { for _, sessionVers := range tlsVersions { for _, resumeVers := range tlsVersions { + cipher := TLS_RSA_WITH_AES_128_CBC_SHA + if sessionVers.version >= VersionTLS13 || resumeVers.version >= VersionTLS13 { + // TLS 1.3 only shares ciphers with TLS 1.2, so + // we skip certain combinations and use a + // different cipher to test with. + cipher = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + if sessionVers.version < VersionTLS12 || resumeVers.version < VersionTLS12 { + continue + } + } + protocols := []protocol{tls} if sessionVers.hasDTLS && resumeVers.hasDTLS { protocols = append(protocols, dtls) @@ -4079,7 +4131,7 @@ resumeSession: true, config: Config{ MaxVersion: sessionVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, }, expectedVersion: sessionVers.version, expectedResumeVersion: resumeVers.version, @@ -4091,12 +4143,12 @@ resumeSession: true, config: Config{ MaxVersion: sessionVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, }, expectedVersion: sessionVers.version, resumeConfig: &Config{ MaxVersion: resumeVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, Bugs: ProtocolBugs{ AllowSessionVersionMismatch: true, }, @@ -4113,12 +4165,12 @@ resumeSession: true, config: Config{ MaxVersion: sessionVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, }, expectedVersion: sessionVers.version, resumeConfig: &Config{ MaxVersion: resumeVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, }, newSessionsOnResume: true, expectResumeRejected: true, @@ -4132,13 +4184,13 @@ resumeSession: true, config: Config{ MaxVersion: sessionVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, }, expectedVersion: sessionVers.version, expectResumeRejected: sessionVers.version != resumeVers.version, resumeConfig: &Config{ MaxVersion: resumeVers.version, - CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, + CipherSuites: []uint16{cipher}, }, expectedResumeVersion: resumeVers.version, }) @@ -4146,13 +4198,16 @@ } } + // TODO(davidben): This test should have a TLS 1.3 variant later. testCases = append(testCases, testCase{ name: "Resume-Client-CipherMismatch", resumeSession: true, config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, }, resumeConfig: &Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA, @@ -4278,6 +4333,7 @@ name: "Renegotiate-Client-SwitchCiphers", renegotiate: 1, config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, }, renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, @@ -4290,6 +4346,7 @@ name: "Renegotiate-Client-SwitchCiphers2", renegotiate: 1, config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, }, renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA}, @@ -4316,6 +4373,7 @@ name: "Renegotiate-FalseStart", renegotiate: 1, config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, NextProtos: []string{"foo"}, }, @@ -5110,6 +5168,7 @@ testType: clientTest, name: "CECPQ1-Client-BadX25519Part", config: Config{ + MaxVersion: VersionTLS12, MinVersion: VersionTLS12, CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, Bugs: ProtocolBugs{ @@ -5124,6 +5183,7 @@ testType: clientTest, name: "CECPQ1-Client-BadNewhopePart", config: Config{ + MaxVersion: VersionTLS12, MinVersion: VersionTLS12, CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, Bugs: ProtocolBugs{ @@ -5138,6 +5198,7 @@ testType: serverTest, name: "CECPQ1-Server-BadX25519Part", config: Config{ + MaxVersion: VersionTLS12, MinVersion: VersionTLS12, CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, Bugs: ProtocolBugs{ @@ -5152,6 +5213,7 @@ testType: serverTest, name: "CECPQ1-Server-BadNewhopePart", config: Config{ + MaxVersion: VersionTLS12, MinVersion: VersionTLS12, CipherSuites: []uint16{TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384}, Bugs: ProtocolBugs{ @@ -5168,6 +5230,7 @@ testCases = append(testCases, testCase{ name: "KeyExchangeInfo-RSA-Client", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, }, // key.pem is a 1024-bit RSA key. @@ -5180,6 +5243,7 @@ testCases = append(testCases, testCase{ name: "KeyExchangeInfo-DHE-Client", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, Bugs: ProtocolBugs{ // This is a 1234-bit prime number, generated @@ -5194,15 +5258,20 @@ testType: serverTest, name: "KeyExchangeInfo-DHE-Server", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, }, // bssl_shim as a server configures a 2048-bit DHE group. flags: []string{"-expect-key-exchange-info", "2048"}, }) + // TODO(davidben): Add TLS 1.3 versions of these tests once the + // handshake is separate. + testCases = append(testCases, testCase{ name: "KeyExchangeInfo-ECDHE-Client", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, CurvePreferences: []CurveID{CurveX25519}, }, @@ -5212,6 +5281,7 @@ testType: serverTest, name: "KeyExchangeInfo-ECDHE-Server", config: Config{ + MaxVersion: VersionTLS12, CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, CurvePreferences: []CurveID{CurveX25519}, },