From: Tobias Brunner Date: Fri, 22 Jan 2021 09:06:05 +0000 (+0100) Subject: tls-server: Select cipher suite also when handling HelloRetryRequest X-Git-Tag: 5.9.2rc1~23^2~10 X-Git-Url: https://git.strongswan.org/?p=strongswan.git;a=commitdiff_plain;h=ab226b3927f87ad1a9cc947368f3c7f797654925 tls-server: Select cipher suite also when handling HelloRetryRequest This was previously treated like a resumption, which it is clearly not. Also added a check that verifies that the same cipher suite is selected during the retry, as per RFC 8446, section 4.1.4. --- diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index 6562fc4..376a193 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -253,7 +253,9 @@ static bool select_suite_and_key(private_tls_server_t *this, return FALSE; } DBG1(DBG_TLS, "using key of type %N", key_type_names, key->get_type(key)); + DESTROY_IF(this->private); this->private = key->get_ref(key); + this->server_auth->purge(this->server_auth, FALSE); this->server_auth->merge(this->server_auth, auth, FALSE); enumerator->destroy(enumerator); return TRUE; @@ -516,7 +518,7 @@ static status_t process_client_hello(private_tls_server_t *this, chunk_from_thing(this->server_random)); } - if (this->suite) + if (this->suite && !retrying(this)) { this->session = chunk_clone(session); this->resume = TRUE; @@ -526,6 +528,8 @@ static status_t process_client_hello(private_tls_server_t *this, } else { + tls_cipher_suite_t original_suite = this->suite; + count = ciphers.len / sizeof(uint16_t); suites = alloca(count * sizeof(tls_cipher_suite_t)); DBG2(DBG_TLS, "received %d TLS cipher suites:", count); @@ -539,6 +543,14 @@ static status_t process_client_hello(private_tls_server_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); return NEED_MORE; } + if (retrying(this) && original_suite != this->suite) + { + DBG1(DBG_TLS, "selected %N instead of %N during retry", + tls_cipher_suite_names, this->suite, tls_cipher_suite_names, + original_suite); + this->alert->add(this->alert, TLS_FATAL, TLS_ILLEGAL_PARAMETER); + return NEED_MORE; + } if (this->tls->get_version_max(this->tls) < TLS_1_3) { rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); @@ -551,6 +563,7 @@ static status_t process_client_hello(private_tls_server_t *this, } else { + chunk_free(&this->session); this->session = chunk_clone(session); } DBG1(DBG_TLS, "negotiated %N using suite %N",