From 8288ed0acee095894f411412664f4e2eb4f59159 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Sat, 23 Sep 2017 08:19:21 +0200 Subject: server name: refuse to resume a session which server name doesn't match That is, follow the RFC6066 requirement that server: "MUST NOT accept the request to resume the session if the server_name extension contains a different name." Signed-off-by: Nikos Mavrogiannopoulos --- lib/db.c | 4 ++++ lib/ext/server_name.c | 40 ++++++++++++++++++++++++++++++++++++++++ lib/ext/server_name.h | 2 ++ 3 files changed, 46 insertions(+) diff --git a/lib/db.c b/lib/db.c index 1955cd096a..0bed7a5b98 100644 --- a/lib/db.c +++ b/lib/db.c @@ -29,6 +29,7 @@ #include #include #include +#include "ext/server_name.h" /** * gnutls_db_set_retrieve_function: @@ -257,6 +258,9 @@ int _gnutls_check_resumed_params(gnutls_session_t session) session->security_parameters.ext_master_secret) return gnutls_assert_val(GNUTLS_E_INVALID_SESSION); + if (!_gnutls_server_name_matches_resumed(session)) + return gnutls_assert_val(GNUTLS_E_INVALID_SESSION); + return 0; } diff --git a/lib/ext/server_name.c b/lib/ext/server_name.c index c6f1882ce2..2395b461af 100644 --- a/lib/ext/server_name.c +++ b/lib/ext/server_name.c @@ -444,3 +444,43 @@ _gnutls_server_name_unpack(gnutls_buffer_st * ps, gnutls_free(priv); return ret; } + +unsigned _gnutls_server_name_matches_resumed(gnutls_session_t session) +{ + server_name_ext_st *priv1, *priv2; + int ret; + gnutls_ext_priv_data_t epriv; + + ret = + _gnutls_ext_get_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + &epriv); + if (ret < 0) /* no server name in this session */ + priv1 = NULL; + else + priv1 = epriv; + + ret = + _gnutls_ext_get_resumed_session_data(session, + GNUTLS_EXTENSION_SERVER_NAME, + &epriv); + if (ret < 0) /* no server name in extensions */ + priv2 = NULL; + else + priv2 = epriv; + + if (priv1 == NULL || priv2 == NULL) { + if (priv1 == priv2) + return 1; + else + return 0; + } + + if (priv1->name_length != priv2->name_length) + return 0; + + if (memcmp(priv1->name, priv2->name, priv1->name_length) != 0) + return 0; + + return 1; +} diff --git a/lib/ext/server_name.h b/lib/ext/server_name.h index dfb705a5fb..95caa33deb 100644 --- a/lib/ext/server_name.h +++ b/lib/ext/server_name.h @@ -33,4 +33,6 @@ typedef struct { extern const extension_entry_st ext_mod_server_name; +unsigned _gnutls_server_name_matches_resumed(gnutls_session_t); + #endif -- cgit v1.2.1