diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 736f703233..a6aa02caa3 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1690,23 +1690,27 @@ OPENSSL_EXPORT size_t SSL_get_all_standard_cipher_names(const char **out, // Once an equal-preference group is used, future directives must be // opcode-less. Inside an equal-preference group, spaces are not allowed. // -// TLS 1.3 ciphers do not participate in this mechanism and instead have a -// built-in preference order. Functions to set cipher lists do not affect TLS -// 1.3, and functions to query the cipher list do not include TLS 1.3 -// ciphers. +// Note: TLS 1.3 ciphersuites are only configurable via +// |SSL_CTX_set_ciphersuites| or |SSL_set_ciphersuites|. Other setter functions have +// no impact on TLS 1.3 ciphersuites. // SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is // substituted when a cipher string starts with 'DEFAULT'. #define SSL_DEFAULT_CIPHER_LIST "ALL" + // SSL_CTX_set_strict_cipher_list configures the cipher list for |ctx|, // evaluating |str| as a cipher string and returning error if |str| contains -// anything meaningless. It returns one on success and zero on failure. +// anything meaningless. It updates |ctx->cipher_list| with any values in +// |ctx->tls13_cipher_list|. +// +// It returns one on success and zero on failure. OPENSSL_EXPORT int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str); // SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating -// |str| as a cipher string. It returns one on success and zero on failure. +// |str| as a cipher string. It updates |ctx->cipher_list| with any values in +// |ctx->tls13_cipher_list|. It returns one on success and zero on failure. // // Prefer to use |SSL_CTX_set_strict_cipher_list|. This function tolerates // garbage inputs, unless an empty cipher list results. However, an empty @@ -1720,24 +1724,34 @@ OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); // SSL_set_strict_cipher_list configures the cipher list for |ssl|, evaluating // |str| as a cipher string and returning error if |str| contains anything -// meaningless. It returns one on success and zero on failure. +// meaningless. +// It updates the cipher list |ssl->config->cipher_list| with any configured +// TLS 1.3 cipher suites by first checking |ssl->config->tls13_cipher_list| and +// otherwise falling back to |ssl->ctx->tls13_cipher_list|. +// +// It returns one on success and zero on failure. OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str); -// SSL_CTX_set_ciphersuites configure the available TLSv1.3 ciphersuites for -// |ctx|, evaluating |str| as a cipher string. It returns one on success and +// SSL_CTX_set_ciphersuites configures the available TLSv1.3 ciphersuites on +// |ctx|, evaluating |str| as a cipher string. It updates |ctx->cipher_list| +// with any values in |ctx->tls13_cipher_list|. It returns one on success and // zero on failure. OPENSSL_EXPORT int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); -// SSL_set_ciphersuites sets the available TLSv1.3 ciphersuites on an |ssl|, -// returning one on success and zero on failure. In OpenSSL, the only -// difference between |SSL_CTX_set_ciphersuites| and |SSL_set_ciphersuites| is -// that the latter copies the |SSL|'s |cipher_list| to its associated -// |SSL_CONNECTION|. In AWS-LC, we track everything on the |ssl|'s |config| so -// duplication is not necessary. +// SSL_set_ciphersuites configures the available TLSv1.3 ciphersuites on +// |ssl|, evaluating |str| as a cipher string. It updates +// |ssl->config->cipher_list| with any values in +// |ssl->config->tls13_cipher_list|. It returns one on success and zero on +// failure. OPENSSL_EXPORT int SSL_set_ciphersuites(SSL *ssl, const char *str); // SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as -// a cipher string. It returns one on success and zero on failure. +// a cipher string. It updates the cipher list |ssl->config->cipher_list| with +// any configured TLS 1.3 cipher suites by first checking +// |ssl->config->tls13_cipher_list| and otherwise falling back to +// |ssl->ctx->tls13_cipher_list|. +// +// It returns one on success and zero on failure. // // Prefer to use |SSL_set_strict_cipher_list|. This function tolerates garbage // inputs, unless an empty cipher list results. However, an empty string which @@ -1746,7 +1760,7 @@ OPENSSL_EXPORT int SSL_set_ciphersuites(SSL *ssl, const char *str); OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str); // SSL_CTX_get_ciphers returns the cipher list for |ctx|, in order of -// preference. +// preference. This includes TLS 1.3 and 1.2 and below cipher suites. OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); // SSL_CTX_cipher_in_group returns one if the |i|th cipher (see @@ -1755,6 +1769,7 @@ OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); OPENSSL_EXPORT int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i); // SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. +// This includes TLS 1.3 and 1.2 and below cipher suites. OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl); diff --git a/ssl/handshake_client.cc b/ssl/handshake_client.cc index b96424f7a0..b785d96a80 100644 --- a/ssl/handshake_client.cc +++ b/ssl/handshake_client.cc @@ -224,6 +224,7 @@ static bool collect_cipher_protocol_ids(STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb, uint32_t mask_k, uint32_t mask_a, uint16_t max_version, uint16_t min_version, bool *any_enabled) { *any_enabled = false; + for (const SSL_CIPHER *cipher : ciphers) { // Skip disabled ciphers if ((cipher->algorithm_mkey & mask_k) || @@ -259,49 +260,33 @@ static bool ssl_write_client_cipher_list(const SSL_HANDSHAKE *hs, CBB *out, return false; } - // Add TLS 1.3 ciphers. - if (hs->max_version >= TLS1_3_VERSION && ssl->ctx->tls13_cipher_list) { - // Use the configured TLSv1.3 ciphers list. - STACK_OF(SSL_CIPHER) *ciphers = ssl->ctx->tls13_cipher_list->ciphers.get(); + // Add all ciphers unless TLS 1.3 only connection + if (hs->min_version < TLS1_3_VERSION && type != ssl_client_hello_inner) { bool any_enabled = false; - if (!collect_cipher_protocol_ids(ciphers, &child, mask_k, + if (!collect_cipher_protocol_ids(SSL_get_ciphers(ssl), &child, mask_k, mask_a, hs->max_version, hs->min_version, &any_enabled)) { return false; } + // If all ciphers were disabled, return the error to the caller. if (!any_enabled) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); return false; } } else if (hs->max_version >= TLS1_3_VERSION) { - // Use the built in TLSv1.3 ciphers. Order ChaCha20-Poly1305 relative to - // AES-GCM based on hardware support. - const bool has_aes_hw = ssl->config->aes_hw_override - ? ssl->config->aes_hw_override_value - : EVP_has_aes_hardware(); - - if (!has_aes_hw && - !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { - return false; - } - if (!CBB_add_u16(&child, TLS1_3_CK_AES_128_GCM_SHA256 & 0xffff) || - !CBB_add_u16(&child, TLS1_3_CK_AES_256_GCM_SHA384 & 0xffff)) { - return false; - } - if (has_aes_hw && - !CBB_add_u16(&child, TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { - return false; - } - } + // Only TLS 1.3 ciphers + STACK_OF(SSL_CIPHER) *ciphers = (ssl->config && ssl->config->tls13_cipher_list) ? + ssl->config->tls13_cipher_list->ciphers.get() : ssl->ctx->tls13_cipher_list->ciphers.get(); - if (hs->min_version < TLS1_3_VERSION && type != ssl_client_hello_inner) { bool any_enabled = false; - if (!collect_cipher_protocol_ids(SSL_get_ciphers(ssl), &child, mask_k, + + if (!collect_cipher_protocol_ids(ciphers, &child, mask_k, mask_a, hs->max_version, hs->min_version, &any_enabled)) { return false; } + // If all ciphers were disabled, return the error to the caller. - if (!any_enabled && hs->max_version < TLS1_3_VERSION) { + if (!any_enabled) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); return false; } diff --git a/ssl/internal.h b/ssl/internal.h index 717759a54c..56a322efad 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -722,6 +722,20 @@ bool ssl_create_cipher_list(UniquePtr *out_cipher_list, const bool has_aes_hw, const char *rule_str, bool strict, bool config_tls13); +// update_cipher_list creates a new |SSLCipherPreferenceList| containing ciphers +// from both |ciphers| and |tls13_ciphers| and assigns it to |dst|. The function: +// +// 1. Creates a copy of |ciphers| +// 2. Removes any stale TLS 1.3 ciphersuites from the copy +// 3. Adds any configured TLS 1.3 ciphersuites from |tls13_ciphers| to the +// front of the list. +// 4. Combines |in_group_flags| from both input lists into |dst->in_group_flags| +// +// Returns one on success, zero on error. +int update_cipher_list(UniquePtr &dst, + UniquePtr &ciphers, + UniquePtr &tls13_ciphers); + // ssl_get_certificate_slot_index returns the |SSL_PKEY_*| certificate slot // index corresponding to the private key type of |pkey|. It returns -1 if not // supported. This was |ssl_cert_type| in OpenSSL 1.0.2. @@ -3244,9 +3258,16 @@ struct SSL_CONFIG { X509_VERIFY_PARAM *param = nullptr; - // crypto + // cipher_list holds all available cipher suites for tls 1.3, + // and 1.2 and below. Any configured ciphersuites here take precedence + // over the parent |SSL_CTX| object. UniquePtr cipher_list; + // tls13_cipher_list holds the default or configured tls1.3 and above + // cipher suites. Any configured ciphersuites here take precedence + // over the parent |SSL_CTX| object. + UniquePtr tls13_cipher_list; + // This is used to hold the local certificate used (i.e. the server // certificate for a server or the client certificate for a client). UniquePtr cert; @@ -3721,6 +3742,18 @@ struct ssl_method_st { const bssl::SSL_X509_METHOD *x509_method; }; +// TLS13_DEFAULT_CIPHER_LIST_AES_HW is the default TLS 1.3 cipher suite +// configuration when AES hardware acceleration is enabled. +#define TLS13_DEFAULT_CIPHER_LIST_AES_HW "TLS_AES_128_GCM_SHA256:" \ + "TLS_AES_256_GCM_SHA384:" \ + "TLS_CHACHA20_POLY1305_SHA256" + +// TLS13_DEFAULT_CIPHER_LIST_NO_AES_HW is the default TLS 1.3 cipher suite +// configuration when no AES hardware acceleration is enabled. +#define TLS13_DEFAULT_CIPHER_LIST_NO_AES_HW "TLS_CHACHA20_POLY1305_SHA256:" \ + "TLS_AES_128_GCM_SHA256:" \ + "TLS_AES_256_GCM_SHA384" + #define MIN_SAFE_FRAGMENT_SIZE 512 struct ssl_ctx_st : public bssl::RefCounted { explicit ssl_ctx_st(const SSL_METHOD *ssl_method); @@ -3754,12 +3787,12 @@ struct ssl_ctx_st : public bssl::RefCounted { // quic_method is the method table corresponding to the QUIC hooks. const SSL_QUIC_METHOD *quic_method = nullptr; - // Currently, cipher_list holds the tls1.2 and below ciphersuites. - // TODO: move |tls13_cipher_list| to |cipher_list| during cipher - // configuration. + // cipher_list holds all available cipher suites for tls 1.3, + // and 1.2 and below bssl::UniquePtr cipher_list; - // tls13_cipher_list holds the tls1.3 and above ciphersuites. + // tls13_cipher_list holds the default or configured tls1.3 and above + // cipher suites. bssl::UniquePtr tls13_cipher_list; X509_STORE *cert_store = nullptr; diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc index fbb1f8de52..a4e79adb69 100644 --- a/ssl/s3_both.cc +++ b/ssl/s3_both.cc @@ -697,7 +697,7 @@ const SSL_CIPHER *ssl_choose_tls13_cipher( const SSL_CIPHER *client_cipher = sk_SSL_CIPHER_value(client_cipher_suites, i); const SSL_CIPHER *candidate = nullptr; if (tls13_ciphers != nullptr) { - // Limit to customized TLS 1.3 ciphers if configured. + // Limit to configured TLS 1.3 ciphers for (size_t j = 0; j < sk_SSL_CIPHER_num(tls13_ciphers); j++) { const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(tls13_ciphers, j); if (cipher != nullptr && cipher->id == client_cipher->id) { @@ -705,9 +705,6 @@ const SSL_CIPHER *ssl_choose_tls13_cipher( break; } } - } else { - // Limit to TLS 1.3 ciphers we know about. - candidate = client_cipher; } if (candidate == nullptr || SSL_CIPHER_get_min_version(candidate) > version || diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc index 312b3438e0..6f7283ca21 100644 --- a/ssl/ssl_cipher.cc +++ b/ssl/ssl_cipher.cc @@ -1234,6 +1234,84 @@ static bool is_known_default_alias_keyword_filter_rule(const char *rule, return false; } +int update_cipher_list(UniquePtr &dst, + UniquePtr &ciphers, + UniquePtr &tls13_ciphers) { + bssl::UniquePtr tmp_cipher_list; + size_t num_removed_tls13_ciphers = 0, num_added_tls13_ciphers = 0; + Array updated_in_group_flags; + + if (ciphers && ciphers->ciphers) { + tmp_cipher_list.reset(sk_SSL_CIPHER_dup(ciphers->ciphers.get())); + } else { + tmp_cipher_list.reset(sk_SSL_CIPHER_new_null()); + } + + if (tmp_cipher_list == nullptr) { + return 0; + } + + // Delete any existing TLSv1.3 ciphersuites. These will be first in the list + while (sk_SSL_CIPHER_num(tmp_cipher_list.get()) > 0 && + SSL_CIPHER_get_min_version(sk_SSL_CIPHER_value(tmp_cipher_list.get(), 0)) + == TLS1_3_VERSION) { + sk_SSL_CIPHER_delete(tmp_cipher_list.get(), 0); + num_removed_tls13_ciphers++; + } + + size_t num_updated_tls12_ciphers = sk_SSL_CIPHER_num(tmp_cipher_list.get()); + + // Add any configure tls 1.3 ciphersuites + if (tls13_ciphers && tls13_ciphers->ciphers) { + STACK_OF(SSL_CIPHER) *tls13_cipher_stack = tls13_ciphers->ciphers.get(); + num_added_tls13_ciphers = sk_SSL_CIPHER_num(tls13_cipher_stack); + for (int i = sk_SSL_CIPHER_num(tls13_cipher_stack) - 1; i >= 0; i--) { + const SSL_CIPHER *tls13_cipher = sk_SSL_CIPHER_value(tls13_cipher_stack, i); + if (!sk_SSL_CIPHER_unshift(tmp_cipher_list.get(), tls13_cipher)) { + return 0; + } + } + } + + + if (!updated_in_group_flags.Init(num_added_tls13_ciphers + + num_updated_tls12_ciphers)) { + return 0; + } + std::fill(updated_in_group_flags.begin(), updated_in_group_flags.end(), + false); + + // Copy in_group_flags from |ctx->tls13_cipher_list| + if (tls13_ciphers && tls13_ciphers->in_group_flags) { + const auto& tls13_flags = tls13_ciphers->in_group_flags; + // Ensure value of last element in |in_group_flags| is 0. The last cipher + // in a list must be the end of any group in that list. + if (tls13_flags[num_added_tls13_ciphers - 1] != 0) { + tls13_flags[num_added_tls13_ciphers - 1] = false; + } + for (size_t i = 0; i < num_added_tls13_ciphers; i++) { + updated_in_group_flags[i] = tls13_flags[i]; + } + } + + // Copy remaining in_group_flags from |ctx->cipher_list| + if (ciphers && ciphers->in_group_flags) { + for (size_t i = 0; i < num_updated_tls12_ciphers; i++) { + updated_in_group_flags[i + num_added_tls13_ciphers] = + ciphers->in_group_flags[i + num_removed_tls13_ciphers]; + } + } + + Span flags_span(updated_in_group_flags.data(), updated_in_group_flags.size()); + UniquePtr new_list = MakeUnique(); + if (!new_list || !new_list->Init(std::move(tmp_cipher_list), flags_span)) { + return 0; + } + + dst = std::move(new_list); + return 1; +} + bool ssl_create_cipher_list(UniquePtr *out_cipher_list, const bool has_aes_hw, const char *rule_str, bool strict, bool config_tls13) { diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index e08bfa5ee6..b19eb13fce 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc @@ -586,7 +586,17 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { return nullptr; } - if (!SSL_CTX_set_strict_cipher_list(ret.get(), SSL_DEFAULT_CIPHER_LIST) || + const bool has_aes_hw = ret->aes_hw_override ? ret->aes_hw_override_value : + EVP_has_aes_hardware(); + const char *cipher_rule; + if (has_aes_hw) { + cipher_rule = TLS13_DEFAULT_CIPHER_LIST_AES_HW; + } else { + cipher_rule = TLS13_DEFAULT_CIPHER_LIST_NO_AES_HW; + } + + if (!SSL_CTX_set_ciphersuites(ret.get(), cipher_rule) || + !SSL_CTX_set_strict_cipher_list(ret.get(), SSL_DEFAULT_CIPHER_LIST) || // Lock the SSL_CTX to the specified version, for compatibility with // legacy uses of SSL_METHOD. !SSL_CTX_set_max_proto_version(ret.get(), method->version) || @@ -2148,13 +2158,11 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) { if (ssl == NULL) { return NULL; } - if (ssl->config == NULL) { - assert(ssl->config); - return NULL; + if (ssl->config && ssl->config->cipher_list) { + return ssl->config->cipher_list->ciphers.get(); } - return ssl->config->cipher_list ? ssl->config->cipher_list->ciphers.get() - : ssl->ctx->cipher_list->ciphers.get(); + return ssl->ctx->cipher_list->ciphers.get(); } const char *SSL_get_cipher_list(const SSL *ssl, int n) { @@ -2178,17 +2186,25 @@ const char *SSL_get_cipher_list(const SSL *ssl, int n) { int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, + if (!ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, false /* not strict */, - false /* don't configure TLSv1.3 ciphers */); + false /* don't configure TLSv1.3 ciphers */)) { + return 0; + } + + return update_cipher_list(ctx->cipher_list, ctx->cipher_list, ctx->tls13_cipher_list); } int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, + if (!ssl_create_cipher_list(&ctx->cipher_list, has_aes_hw, str, true /* strict */, - false /* don't configure TLSv1.3 ciphers */); + false /* don't configure TLSv1.3 ciphers */)) { + return 0; + } + + return update_cipher_list(ctx->cipher_list, ctx->cipher_list, ctx->tls13_cipher_list); } int SSL_set_cipher_list(SSL *ssl, const char *str) { @@ -2198,17 +2214,29 @@ int SSL_set_cipher_list(SSL *ssl, const char *str) { const bool has_aes_hw = ssl->config->aes_hw_override ? ssl->config->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, + if (!ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, false /* not strict */, - false /* don't configure TLSv1.3 ciphers */); + false /* don't configure TLSv1.3 ciphers */)) { + return 0; + } + + UniquePtr &tls13_ciphers = ssl->config->tls13_cipher_list ? ssl->config->tls13_cipher_list : + ssl->ctx->tls13_cipher_list; + + return update_cipher_list(ssl->config->cipher_list, ssl->config->cipher_list, tls13_ciphers); } int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) { const bool has_aes_hw = ctx->aes_hw_override ? ctx->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ctx->tls13_cipher_list, has_aes_hw, str, + + if (!ssl_create_cipher_list(&ctx->tls13_cipher_list, has_aes_hw, str, false /* not strict */, - true /* only configure TLSv1.3 ciphers */); + true /* only configure TLSv1.3 ciphers */)) { + return 0; + } + + return update_cipher_list(ctx->cipher_list, ctx->cipher_list, ctx->tls13_cipher_list); } int SSL_set_ciphersuites(SSL *ssl, const char *str) { @@ -2218,9 +2246,16 @@ int SSL_set_ciphersuites(SSL *ssl, const char *str) { const bool has_aes_hw = ssl->config->aes_hw_override ? ssl->config->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, - false /* not strict */, - true /* configure TLSv1.3 ciphers */); + if (!ssl_create_cipher_list(&ssl->config->tls13_cipher_list, + has_aes_hw, str, false /* not strict */, + true /* configure TLSv1.3 ciphers */)) { + return 0; + } + + UniquePtr &ciphers = ssl->config->cipher_list ? ssl->config->cipher_list : + ssl->ctx->cipher_list; + + return update_cipher_list(ssl->config->cipher_list, ciphers, ssl->config->tls13_cipher_list); } int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { @@ -2230,9 +2265,16 @@ int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { const bool has_aes_hw = ssl->config->aes_hw_override ? ssl->config->aes_hw_override_value : EVP_has_aes_hardware(); - return ssl_create_cipher_list(&ssl->config->cipher_list, has_aes_hw, str, - true /* strict */, - false /* don't configure TLSv1.3 ciphers */); + if (!ssl_create_cipher_list(&ssl->config->cipher_list, + has_aes_hw, str, true /* strict */, + false /* don't configure TLSv1.3 ciphers */)) { + return 0; + } + + UniquePtr &tls13_ciphers = ssl->config->tls13_cipher_list ? ssl->config->tls13_cipher_list : + ssl->ctx->tls13_cipher_list; + + return update_cipher_list(ssl->config->cipher_list, ssl->config->cipher_list, tls13_ciphers); } const char *SSL_get_servername(const SSL *ssl, const int type) { diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index f85ecc0654..9de0cb42b8 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc @@ -1420,18 +1420,6 @@ static STACK_OF(SSL_CIPHER) *tls13_ciphers(const SSL_CTX *ctx) { return ctx->tls13_cipher_list->ciphers.get(); } -// TODO: replace this helper function with |SSL_CTX_cipher_in_group| -// after moving |tls13_cipher_list| to |cipher_list|. -static int cipher_in_group(const SSL_CTX *ctx, size_t i, bool tlsv13_ciphers) { - if (!tlsv13_ciphers) { - return SSL_CTX_cipher_in_group(ctx, i); - } - if (i >= sk_SSL_CIPHER_num(tls13_ciphers(ctx))) { - return 0; - } - return ctx->tls13_cipher_list->in_group_flags[i]; -} - static std::string CipherListToString(SSL_CTX *ctx, bool tlsv13_ciphers) { bool in_group = false; std::string ret; @@ -1439,7 +1427,7 @@ static std::string CipherListToString(SSL_CTX *ctx, bool tlsv13_ciphers) { tlsv13_ciphers ? tls13_ciphers(ctx) : SSL_CTX_get_ciphers(ctx); for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i); - if (!in_group && cipher_in_group(ctx, i, tlsv13_ciphers)) { + if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) { ret += "\t[\n"; in_group = true; } @@ -1449,7 +1437,7 @@ static std::string CipherListToString(SSL_CTX *ctx, bool tlsv13_ciphers) { } ret += SSL_CIPHER_get_name(cipher); ret += "\n"; - if (in_group && !cipher_in_group(ctx, i, tlsv13_ciphers)) { + if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) { ret += "\t]\n"; in_group = false; } @@ -1470,7 +1458,7 @@ static bool CipherListsEqual(SSL_CTX *ctx, const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i); if (expected[i].id != SSL_CIPHER_get_id(cipher) || expected[i].in_group_flag != - !!cipher_in_group(ctx, i, tlsv13_ciphers)) { + !!SSL_CTX_cipher_in_group(ctx, i)) { return false; } } @@ -1616,6 +1604,11 @@ TEST(SSLTest, CipherRules) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); + // We configure default TLS 1.3 ciphersuites in |SSL_CTX| which pollute + // |ctx->cipher_list|. Set it to an empty list so we can test TLS 1.2 + // configurations. + ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), "")); + // Test lax mode. ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule)); EXPECT_TRUE( @@ -1654,6 +1647,11 @@ TEST(SSLTest, CipherRules) { bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); + // We configure default TLS 1.3 ciphersuites in |SSL_CTX| which pollute + // |ctx->cipher_list|. Set it to an empty list so we can test TLS 1.2 + // configurations. + ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), "")); + EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), t.rule)); ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_CIPHER_MATCH); ERR_clear_error(); @@ -2823,6 +2821,252 @@ TEST(SSLTest, FindingCipher) { ASSERT_FALSE(cipher3); } +TEST(SSLTest, SSLGetCiphersReturnsTLS13Default) { + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + // Configure only TLS 1.3. + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)); + + bssl::UniquePtr client, server; + // Have to ensure config is not shed per current implementation of SSL_get_ciphers. + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), server_ctx.get(), + ClientConfig(), false)); + + // Ensure default TLS 1.3 Ciphersuites are present + const SSL_CIPHER *cipher1 = SSL_get_cipher_by_value(TLS1_3_CK_AES_128_GCM_SHA256 & 0xFFFF); + ASSERT_TRUE(cipher1); + const SSL_CIPHER *cipher2 = SSL_get_cipher_by_value(TLS1_3_CK_AES_256_GCM_SHA384 & 0xFFFF); + ASSERT_TRUE(cipher2); + const SSL_CIPHER *cipher3 = SSL_get_cipher_by_value(TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xFFFF); + ASSERT_TRUE(cipher3); + + STACK_OF(SSL_CIPHER) *client_ciphers = SSL_get_ciphers(client.get()); + STACK_OF(SSL_CIPHER) *server_ciphers = SSL_get_ciphers(server.get()); + + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(client_ciphers, NULL, cipher1)); + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(client_ciphers, NULL, cipher2)); + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(client_ciphers, NULL, cipher3)); + + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(server_ciphers, NULL, cipher1)); + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(server_ciphers, NULL, cipher2)); + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(server_ciphers, NULL, cipher3)); +} + +TEST(SSLTest, TLS13ConfigCiphers) { + // This configures SSL_CTX objects with default TLS 1.2 and 1.3 ciphersuites + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)); + + // Restrict TLS 1.3 ciphersuite + ASSERT_TRUE(SSL_CTX_set_ciphersuites(client_ctx.get(), "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384")); + ASSERT_TRUE(SSL_CTX_set_ciphersuites(server_ctx.get(), "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384")); + + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(), server_ctx.get())); + + // Modify ciphersuites on the SSL object, this modifies ssl->config + ASSERT_TRUE(SSL_set_ciphersuites(client.get(), "TLS_AES_256_GCM_SHA384")); + ASSERT_TRUE(SSL_set_ciphersuites(server.get(), "TLS_AES_128_GCM_SHA256")); + + // Handshake should fail as config objects have no shared cipher. + ASSERT_FALSE(CompleteHandshakes(client.get(), server.get())); + ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_SHARED_CIPHER); + + bssl::UniquePtr client2, server2; + ASSERT_TRUE(CreateClientAndServer(&client2, &server2, client_ctx.get(), server_ctx.get())); + + // Modify ciphersuites on the SSL object, this modifies ssl->config + ASSERT_TRUE(SSL_set_ciphersuites(client2.get(), "TLS_CHACHA20_POLY1305_SHA256")); + ASSERT_TRUE(SSL_set_ciphersuites(server2.get(), "TLS_CHACHA20_POLY1305_SHA256")); + + ASSERT_TRUE(CompleteHandshakes(client2.get(), server2.get())); + ASSERT_EQ(SSL_CIPHER_get_id(SSL_get_current_cipher(client2.get())), (uint32_t)TLS1_3_CK_CHACHA20_POLY1305_SHA256); + ASSERT_EQ(SSL_CIPHER_get_id(SSL_get_current_cipher(server2.get())), (uint32_t)TLS1_3_CK_CHACHA20_POLY1305_SHA256); +} + +TEST(SSLTest, TLS13ConfigCtxInteraction) { + // This configures SSL_CTX objects with default TLS 1.2 and 1.3 ciphersuites + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)); + + // Restrict TLS 1.3 ciphersuite on the SSL_CTX objects + ASSERT_TRUE(SSL_CTX_set_ciphersuites(client_ctx.get(), "TLS_AES_128_GCM_SHA256")); + ASSERT_TRUE(SSL_CTX_set_ciphersuites(server_ctx.get(), "TLS_AES_128_GCM_SHA256")); + + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(), server_ctx.get())); + + // Modify TLS 1.3 ciphersuites for client's SSL object, but not server + ASSERT_TRUE(SSL_set_ciphersuites(client.get(), "TLS_AES_256_GCM_SHA384")); + + // Handshake should fail as client SSL config and server CTX objects have no + // shared TLS 1.3 cipher. + ASSERT_FALSE(CompleteHandshakes(client.get(), server.get())); + ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_SHARED_CIPHER); + + ERR_clear_error(); + + bssl::UniquePtr client2, server2; + ASSERT_TRUE(CreateClientAndServer(&client2, &server2, client_ctx.get(), server_ctx.get())); + + // Modify TLS 1.3 ciphersuites for server2 SSL object, but not client + ASSERT_TRUE(SSL_set_ciphersuites(server2.get(), "TLS_AES_256_GCM_SHA384")); + + // Handshake should fail as server SSL config and client CTX objects have no + // shared TLS 1.3 cipher. + ASSERT_FALSE(CompleteHandshakes(client2.get(), server2.get())); + ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_SHARED_CIPHER); +} + +TEST(SSLTest, TLS12ConfigCiphers) { + // This configures SSL_CTX objects with default TLS 1.2 and 1.3 ciphersuites + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION)); + + // Restrict TLS 1.2 ciphersuite + ASSERT_TRUE(SSL_CTX_set_cipher_list(client_ctx.get(), "TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_AES_256_GCM_SHA384")); + ASSERT_TRUE(SSL_CTX_set_cipher_list(server_ctx.get(), "TLS_RSA_WITH_AES_256_CBC_SHA:TLS_RSA_WITH_AES_256_GCM_SHA384")); + + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(), server_ctx.get())); + + // Modify ciphersuites on the SSL object and introduce mismatch, this modifies ssl->config + ASSERT_TRUE(SSL_set_cipher_list(client.get(), "TLS_RSA_WITH_AES_256_CBC_SHA")); + ASSERT_TRUE(SSL_set_cipher_list(server.get(), "TLS_RSA_WITH_AES_256_GCM_SHA384")); + + // Handshake should fail as config objects have no shared cipher. + ASSERT_FALSE(CompleteHandshakes(client.get(), server.get())); + ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_SHARED_CIPHER); + + ERR_clear_error(); + + bssl::UniquePtr client2, server2; + ASSERT_TRUE(CreateClientAndServer(&client2, &server2, client_ctx.get(), server_ctx.get())); + + // Modify ciphersuites on the SSL object with a new third cipher, this modifies ssl->config + ASSERT_TRUE(SSL_set_cipher_list(client2.get(), "TLS_RSA_WITH_AES_128_CBC_SHA")); + ASSERT_TRUE(SSL_set_cipher_list(server2.get(), "TLS_RSA_WITH_AES_128_CBC_SHA")); + + ASSERT_TRUE(CompleteHandshakes(client2.get(), server2.get())); + ASSERT_EQ(SSL_CIPHER_get_id(SSL_get_current_cipher(client2.get())), (uint32_t)TLS1_CK_RSA_WITH_AES_128_SHA); + ASSERT_EQ(SSL_CIPHER_get_id(SSL_get_current_cipher(server2.get())), (uint32_t)TLS1_CK_RSA_WITH_AES_128_SHA); +} + +TEST(SSLTest, TLS12ConfigCtxInteraction) { + // This configures SSL_CTX objects with default TLS 1.2 and 1.3 ciphersuites + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_2_VERSION)); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION)); + + // Restrict TLS 1.2 ciphersuites on the SSL_CTX objects + ASSERT_TRUE(SSL_CTX_set_cipher_list(client_ctx.get(), "TLS_RSA_WITH_AES_256_CBC_SHA")); + ASSERT_TRUE(SSL_CTX_set_cipher_list(server_ctx.get(), "TLS_RSA_WITH_AES_256_CBC_SHA")); + + bssl::UniquePtr client, server; + ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(), server_ctx.get())); + + // Modify TLS 1.2 ciphersuite for client's SSL object, but not server + ASSERT_TRUE(SSL_set_cipher_list(client.get(), "TLS_RSA_WITH_AES_256_GCM_SHA384")); + + // Handshake should fail as client SSL config and server CTX objects have no + // shared TLS 1.2 cipher. + ASSERT_FALSE(CompleteHandshakes(client.get(), server.get())); + ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_SHARED_CIPHER); + + ERR_clear_error(); + + bssl::UniquePtr client2, server2; + ASSERT_TRUE(CreateClientAndServer(&client2, &server2, client_ctx.get(), server_ctx.get())); + + // Modify TLS 1.2 ciphersuites for server2 SSL object, but not client + ASSERT_TRUE(SSL_set_cipher_list(server2.get(), "TLS_RSA_WITH_AES_256_GCM_SHA384")); + + // Handshake should fail as server SSL config and client CTX objects have no + // shared TLS 1.2 cipher. + ASSERT_FALSE(CompleteHandshakes(client2.get(), server2.get())); + ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_SHARED_CIPHER); +} + +TEST(SSLTest, SSLGetCiphersReturnsTLS13Custom) { + bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); + bssl::UniquePtr server_ctx = + CreateContextWithTestCertificate(TLS_method()); + ASSERT_TRUE(client_ctx); + ASSERT_TRUE(server_ctx); + + // Configure custom TLS 1.3 Ciphersuites + SSL_CTX_set_ciphersuites(server_ctx.get(), "TLS_AES_128_GCM_SHA256"); + SSL_CTX_set_ciphersuites(client_ctx.get(), "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384"); + + // Configure only TLS 1.3. + ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION)); + ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)); + + bssl::UniquePtr client, server; + // Have to ensure config is not shed per current implementation of SSL_get_ciphers. + ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(), server_ctx.get(), + ClientConfig(), false)); + + ASSERT_TRUE(CompleteHandshakes(client.get(), server.get())); + // Ensure default TLS 1.3 Ciphersuites are present + const SSL_CIPHER *cipher1 = SSL_get_cipher_by_value(TLS1_3_CK_AES_128_GCM_SHA256 & 0xFFFF); + ASSERT_TRUE(cipher1); + const SSL_CIPHER *cipher2 = SSL_get_cipher_by_value(TLS1_3_CK_AES_256_GCM_SHA384 & 0xFFFF); + ASSERT_TRUE(cipher2); + const SSL_CIPHER *cipher3 = SSL_get_cipher_by_value(TLS1_3_CK_CHACHA20_POLY1305_SHA256 & 0xFFFF); + ASSERT_TRUE(cipher3); + + STACK_OF(SSL_CIPHER) *client_ciphers = SSL_get_ciphers(client.get()); + STACK_OF(SSL_CIPHER) *server_ciphers = SSL_get_ciphers(server.get()); + + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(client_ciphers, NULL, cipher1)); + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(client_ciphers, NULL, cipher2)); + ASSERT_FALSE(sk_SSL_CIPHER_find_awslc(client_ciphers, NULL, cipher3)); + + ASSERT_TRUE(sk_SSL_CIPHER_find_awslc(server_ciphers, NULL, cipher1)); + ASSERT_FALSE(sk_SSL_CIPHER_find_awslc(server_ciphers, NULL, cipher2)); + ASSERT_FALSE(sk_SSL_CIPHER_find_awslc(server_ciphers, NULL, cipher3)); +} + TEST(SSLTest, GetClientCiphersAfterHandshakeFailure1_3) { bssl::UniquePtr client_ctx(SSL_CTX_new(TLS_method())); bssl::UniquePtr server_ctx = CreateContextWithTestCertificate(TLS_method()); @@ -4720,39 +4964,58 @@ TEST(SSLTest, ClientHello) { uint16_t max_version; std::vector expected; } kTests[] = { - {TLS1_VERSION, - {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09, - 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, - 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, - 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, - {TLS1_1_VERSION, - {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09, - 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, - 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, - 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, - 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, - {TLS1_2_VERSION, - {0x16, 0x03, 0x01, 0x00, 0x86, 0x01, 0x00, 0x00, 0x82, 0x03, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xcc, 0xa9, - 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09, - 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x28, 0x00, 0x9c, - 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x01, 0x00, 0x00, 0x37, - 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, - 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, - 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, - 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, - 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01}}, - // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our - // implementation has settled enough that it won't change. + {TLS1_VERSION, + {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, + 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, + {TLS1_1_VERSION, + {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, + 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}}, + {TLS1_2_VERSION, + {0x16, 0x03, 0x01, 0x00, 0x86, 0x01, 0x00, 0x00, 0x82, 0x03, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xcc, 0xa9, + 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09, + 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x28, 0x00, 0x9c, + 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x01, 0x00, 0x00, 0x37, + 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, + 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, + 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, + 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, + 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01}}, + {TLS1_3_VERSION, + {0x16, 0x03, 0x01, 0x00, 0xe9, 0x01, 0x00, 0x00, 0xe5, 0x03, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, + 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, + 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x28, + 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35, 0x01, 0x00, + 0x00, 0x74, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, + 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, + 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, + 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x33, 0x00, + 0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x2b, 0x00, + 0x09, 0x08, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x03, 0x01}} }; for (const auto &t : kTests) { @@ -4766,6 +5029,9 @@ TEST(SSLTest, ClientHello) { ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version)); ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)); + // Explicitly set TLS 1.3 ciphersuites so CPU capabilities don't affect order + ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), TLS13_DEFAULT_CIPHER_LIST_AES_HW)); + bssl::UniquePtr ssl(SSL_new(ctx.get())); ASSERT_TRUE(ssl); std::vector client_hello; @@ -4775,8 +5041,19 @@ TEST(SSLTest, ClientHello) { constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header 1 + 3 + // handshake message header 2; // client_version - ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE); - OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE); + + int pre = client_hello.size(); + if (t.max_version == TLS1_3_VERSION) { + ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE + 1 + SSL3_SESSION_ID_SIZE); + OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE + 1 + SSL3_SESSION_ID_SIZE); + // Jump to key share extension and zero out the key + OPENSSL_memset(client_hello.data() + 187, 0, 32); + } else { + ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE); + OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE); + } + int post = client_hello.size(); + ASSERT_EQ(pre, post); if (client_hello != t.expected) { ADD_FAILURE() << "ClientHellos did not match."; @@ -6415,12 +6692,12 @@ TEST(SSLTest, EmptyCipherList) { // Configuring the empty cipher list with |SSL_CTX_set_cipher_list| // succeeds. EXPECT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), "")); - // The cipher list is updated to empty. - EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get()))); + // The cipher list should only be populated with default TLS 1.3 ciphersuites + EXPECT_EQ(3u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get()))); - // Configuring the empty cipher list with |SSL_CTX_set_ciphersuites| - // also succeeds. + // Configuring the empty cipher list with |SSL_CTX_set_ciphersuites| works EXPECT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), "")); + EXPECT_EQ(0u, sk_SSL_CIPHER_num(ctx->tls13_cipher_list->ciphers.get())); EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get()))); // Configuring the empty cipher list with |SSL_CTX_set_strict_cipher_list| diff --git a/ssl/tls13_server.cc b/ssl/tls13_server.cc index 95452fb1ce..8d8d500efe 100644 --- a/ssl/tls13_server.cc +++ b/ssl/tls13_server.cc @@ -112,7 +112,12 @@ static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs, static const SSL_CIPHER *choose_tls13_cipher(const SSL *ssl) { STACK_OF(SSL_CIPHER) *tls13_ciphers = nullptr; - if (ssl->ctx->tls13_cipher_list && + // First check config, otherwise fallback to ctx preferences. + if (ssl->config && ssl->config->tls13_cipher_list && + ssl->config->tls13_cipher_list.get()->ciphers && + sk_SSL_CIPHER_num(ssl->config->tls13_cipher_list.get()->ciphers.get()) > 0) { + tls13_ciphers = ssl->config->tls13_cipher_list.get()->ciphers.get(); + } else if (ssl->ctx->tls13_cipher_list && ssl->ctx->tls13_cipher_list.get()->ciphers && sk_SSL_CIPHER_num(ssl->ctx->tls13_cipher_list.get()->ciphers.get()) > 0) { tls13_ciphers = ssl->ctx->tls13_cipher_list.get()->ciphers.get();