summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2017-09-23 08:19:21 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-09-24 11:00:45 +0200
commit7dce47feec54764bdc0089631c94821243e9c2c6 (patch)
tree91ef4e27f955ce217e978a89b3576653b9b3610b
parent78fb46afbe738c780ec056a5da18683344b0dc82 (diff)
downloadgnutls-7dce47feec54764bdc0089631c94821243e9c2c6.tar.gz
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 <nmav@gnutls.org>
-rw-r--r--lib/db.c4
-rw-r--r--lib/ext/server_name.c46
-rw-r--r--lib/ext/server_name.h2
3 files changed, 52 insertions, 0 deletions
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 <db.h>
#include <session_pack.h>
#include <datum.h>
+#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 1454818967..ed79de7d3b 100644
--- a/lib/ext/server_name.c
+++ b/lib/ext/server_name.c
@@ -517,3 +517,49 @@ _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->server_names_size != priv2->server_names_size)
+ return 0;
+
+ if (priv1->server_names_size == 0)
+ return 1;
+
+ if (priv1->server_names[0].name_length != priv2->server_names[0].name_length)
+ return 0;
+
+ if (memcmp(priv1->server_names[0].name, priv2->server_names[0].name, priv1->server_names[0].name_length) != 0)
+ return 0;
+
+ return 1;
+}
diff --git a/lib/ext/server_name.h b/lib/ext/server_name.h
index a079a62066..8fbe323ab1 100644
--- a/lib/ext/server_name.h
+++ b/lib/ext/server_name.h
@@ -40,4 +40,6 @@ typedef struct {
extern const extension_entry_st ext_mod_server_name;
+unsigned _gnutls_server_name_matches_resumed(gnutls_session_t);
+
#endif