From 3abcbf82b5fb83730784e607999bd3df0d19aca5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 22 Jan 2021 10:19:57 +0100 Subject: [PATCH] tls-peer: Verify server selects the same cipher suite after HelloRetryRequest This is as per RFC 8446, section 4.1.4. --- src/libtls/tls_peer.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index dac3acad8..1b755ea34 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -132,6 +132,11 @@ struct private_tls_peer_t { */ tls_named_group_t requested_curve; + /** + * Original cipher suite in HelloRetryRequest + */ + tls_cipher_suite_t original_suite; + /** * Cookie extension received in HelloRetryRequest */ @@ -342,6 +347,14 @@ static status_t process_server_hello(private_tls_peer_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); return NEED_MORE; } + if (this->original_suite && this->original_suite != suite) + { + DBG1(DBG_TLS, "server selected %N instead of %N after retry", + tls_cipher_suite_names, suite, tls_cipher_suite_names, + this->original_suite); + this->alert->add(this->alert, TLS_FATAL, TLS_ILLEGAL_PARAMETER); + return NEED_MORE; + } DBG1(DBG_TLS, "negotiated %N using suite %N", tls_version_names, version, tls_cipher_suite_names, suite); free(this->session.ptr); @@ -390,6 +403,7 @@ static status_t process_server_hello(private_tls_peer_t *this, DESTROY_IF(this->dh); this->dh = NULL; + this->original_suite = suite; this->requested_curve = key_type; this->cookie = chunk_clone(cookie); this->state = STATE_INIT;