| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/ssl/ssl_cipher_suite_names.h" |
| |
| #include "base/macros.h" |
| #include "base/strings/stringprintf.h" |
| #include "net/ssl/ssl_connection_status_flags.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| int kObsoleteVersion = SSL_CONNECTION_VERSION_TLS1; |
| int kModernVersion = SSL_CONNECTION_VERSION_TLS1_2; |
| |
| uint16_t kModernCipherSuite = |
| 0xc02f; /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */ |
| |
| uint16_t kObsoleteCipherObsoleteKeyExchange = |
| 0x67; /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ |
| uint16_t kObsoleteCipherModernKeyExchange = |
| 0x9e; /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */ |
| uint16_t kModernCipherObsoleteKeyExchange = |
| 0xc014; /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */ |
| uint16_t kModernCipherModernKeyExchange = |
| 0xc02f; /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */ |
| |
| int MakeConnectionStatus(int version, uint16_t cipher_suite) { |
| int connection_status = 0; |
| |
| SSLConnectionStatusSetVersion(version, &connection_status); |
| SSLConnectionStatusSetCipherSuite(cipher_suite, &connection_status); |
| |
| return connection_status; |
| } |
| |
| TEST(CipherSuiteNamesTest, Basic) { |
| const char *key_exchange, *cipher, *mac; |
| bool is_aead, is_tls13; |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0xc001); |
| EXPECT_STREQ("ECDH_ECDSA", key_exchange); |
| EXPECT_STREQ("NULL", cipher); |
| EXPECT_STREQ("HMAC-SHA1", mac); |
| EXPECT_FALSE(is_aead); |
| EXPECT_FALSE(is_tls13); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x009f); |
| EXPECT_STREQ("DHE_RSA", key_exchange); |
| EXPECT_STREQ("AES_256_GCM", cipher); |
| EXPECT_TRUE(is_aead); |
| EXPECT_FALSE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0xcca9); |
| EXPECT_STREQ("ECDHE_ECDSA", key_exchange); |
| EXPECT_STREQ("CHACHA20_POLY1305", cipher); |
| EXPECT_TRUE(is_aead); |
| EXPECT_FALSE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| |
| // Non-standard variant. |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0xcc14); |
| EXPECT_STREQ("ECDHE_ECDSA", key_exchange); |
| EXPECT_STREQ("CHACHA20_POLY1305", cipher); |
| EXPECT_TRUE(is_aead); |
| EXPECT_FALSE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0xff31); |
| EXPECT_STREQ("???", key_exchange); |
| EXPECT_STREQ("???", cipher); |
| EXPECT_STREQ("???", mac); |
| EXPECT_FALSE(is_aead); |
| EXPECT_FALSE(is_tls13); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x1301); |
| EXPECT_STREQ("AES_128_GCM", cipher); |
| EXPECT_TRUE(is_aead); |
| EXPECT_TRUE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| EXPECT_EQ(nullptr, key_exchange); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x1302); |
| EXPECT_STREQ("AES_256_GCM", cipher); |
| EXPECT_TRUE(is_aead); |
| EXPECT_TRUE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| EXPECT_EQ(nullptr, key_exchange); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x1303); |
| EXPECT_STREQ("CHACHA20_POLY1305", cipher); |
| EXPECT_TRUE(is_aead); |
| EXPECT_TRUE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| EXPECT_EQ(nullptr, key_exchange); |
| } |
| |
| TEST(CipherSuiteNamesTest, ParseSSLCipherString) { |
| uint16_t cipher_suite = 0; |
| EXPECT_TRUE(ParseSSLCipherString("0x0004", &cipher_suite)); |
| EXPECT_EQ(0x00004u, cipher_suite); |
| |
| EXPECT_TRUE(ParseSSLCipherString("0xBEEF", &cipher_suite)); |
| EXPECT_EQ(0xBEEFu, cipher_suite); |
| } |
| |
| TEST(CipherSuiteNamesTest, ParseSSLCipherStringFails) { |
| const char* const cipher_strings[] = { |
| "0004", |
| "0x004", |
| "0xBEEFY", |
| }; |
| |
| for (size_t i = 0; i < arraysize(cipher_strings); ++i) { |
| uint16_t cipher_suite = 0; |
| EXPECT_FALSE(ParseSSLCipherString(cipher_strings[i], &cipher_suite)); |
| } |
| } |
| |
| TEST(CipherSuiteNamesTest, ObsoleteSSLStatusProtocol) { |
| // Obsolete |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL, |
| ObsoleteSSLStatus(MakeConnectionStatus(SSL_CONNECTION_VERSION_SSL2, |
| kModernCipherSuite))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL, |
| ObsoleteSSLStatus(MakeConnectionStatus(SSL_CONNECTION_VERSION_SSL3, |
| kModernCipherSuite))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL, |
| ObsoleteSSLStatus(MakeConnectionStatus(SSL_CONNECTION_VERSION_TLS1, |
| kModernCipherSuite))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| SSL_CONNECTION_VERSION_TLS1_1, kModernCipherSuite))); |
| |
| // Modern |
| EXPECT_EQ(OBSOLETE_SSL_NONE, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| SSL_CONNECTION_VERSION_TLS1_2, kModernCipherSuite))); |
| EXPECT_EQ(OBSOLETE_SSL_NONE, |
| ObsoleteSSLStatus(MakeConnectionStatus(SSL_CONNECTION_VERSION_QUIC, |
| kModernCipherSuite))); |
| } |
| |
| TEST(CipherSuiteNamesTest, ObsoleteSSLStatusProtocolAndCipherSuite) { |
| // Cartesian combos |
| // As above, some of these combinations can't happen in practice. |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL | OBSOLETE_SSL_MASK_KEY_EXCHANGE | |
| OBSOLETE_SSL_MASK_CIPHER, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kObsoleteVersion, kObsoleteCipherObsoleteKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL | OBSOLETE_SSL_MASK_KEY_EXCHANGE, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kObsoleteVersion, kObsoleteCipherModernKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL | OBSOLETE_SSL_MASK_CIPHER, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kObsoleteVersion, kModernCipherObsoleteKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_PROTOCOL, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kObsoleteVersion, kModernCipherModernKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_KEY_EXCHANGE | OBSOLETE_SSL_MASK_CIPHER, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kModernVersion, kObsoleteCipherObsoleteKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_KEY_EXCHANGE, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kModernVersion, kObsoleteCipherModernKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_MASK_CIPHER, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kModernVersion, kModernCipherObsoleteKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_NONE, |
| ObsoleteSSLStatus(MakeConnectionStatus( |
| kModernVersion, kModernCipherModernKeyExchange))); |
| EXPECT_EQ(OBSOLETE_SSL_NONE, ObsoleteSSLStatus(MakeConnectionStatus( |
| SSL_CONNECTION_VERSION_TLS1_3, |
| 0x1301 /* AES_128_GCM_SHA256 */))); |
| } |
| |
| TEST(CipherSuiteNamesTest, HTTP2CipherSuites) { |
| // Picked some random cipher suites. |
| EXPECT_FALSE( |
| IsTLSCipherSuiteAllowedByHTTP2(0x0 /* TLS_NULL_WITH_NULL_NULL */)); |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0x39 /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */)); |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xc5 /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */)); |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xc00f /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */)); |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xc083 /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */)); |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xc014 /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */)); |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0x9c /* TLS_RSA_WITH_AES_128_GCM_SHA256 */)); |
| |
| // Non-existent cipher suite. |
| EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(0xffff)) << "Doesn't exist!"; |
| |
| // HTTP/2-compatible ones. |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xcc13 /* ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard) */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xcc14 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard) */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xcca8 /* ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( |
| 0xcca9 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(0x1301 /* AES_128_GCM_SHA256 */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(0x1302 /* AES_256_GCM_SHA384 */)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(0x1303 /* CHACHA20_POLY1305 */)); |
| } |
| |
| TEST(CipherSuiteNamesTest, CECPQ1) { |
| const std::vector<uint16_t> kCECPQ1CipherSuites = { |
| 0x16b7, // TLS_CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256 (non-standard) |
| 0x16b8, // TLS_CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (non-standard) |
| 0x16b9, // TLS_CECPQ1_RSA_WITH_AES_256_GCM_SHA384 (non-standard) |
| 0x16ba, // TLS_CECPQ1_ECDSA_WITH_AES_256_GCM_SHA384 (non-standard) |
| }; |
| const char *key_exchange, *cipher, *mac; |
| bool is_aead, is_tls13; |
| |
| for (const uint16_t cipher_suite_id : kCECPQ1CipherSuites) { |
| SCOPED_TRACE(base::StringPrintf("cipher suite %x", cipher_suite_id)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(cipher_suite_id)); |
| |
| int connection_status = |
| MakeConnectionStatus(kModernVersion, cipher_suite_id); |
| EXPECT_EQ(OBSOLETE_SSL_NONE, ObsoleteSSLStatus(connection_status)); |
| EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2(cipher_suite_id)); |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| cipher_suite_id); |
| EXPECT_TRUE(is_aead); |
| EXPECT_FALSE(is_tls13); |
| EXPECT_EQ(nullptr, mac); |
| } |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x16b7); |
| EXPECT_STREQ("CECPQ1_RSA", key_exchange); |
| EXPECT_STREQ("CHACHA20_POLY1305", cipher); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x16b8); |
| EXPECT_STREQ("CECPQ1_ECDSA", key_exchange); |
| EXPECT_STREQ("CHACHA20_POLY1305", cipher); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x16b9); |
| EXPECT_STREQ("CECPQ1_RSA", key_exchange); |
| EXPECT_STREQ("AES_256_GCM", cipher); |
| |
| SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, &is_tls13, |
| 0x16ba); |
| EXPECT_STREQ("CECPQ1_ECDSA", key_exchange); |
| EXPECT_STREQ("AES_256_GCM", cipher); |
| } |
| |
| } // anonymous namespace |
| |
| } // namespace net |