]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
server name: refuse to resume a session which server name doesn't match
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 23 Sep 2017 06:19:21 +0000 (08:19 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 23 Sep 2017 08:47:21 +0000 (10:47 +0200)
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>
lib/db.c
lib/ext/server_name.c
lib/ext/server_name.h

index 1955cd096af27b23d1d2a2e231a0e04ccae00fbb..0bed7a5b98b50eb1b5527a6ff584a9dafe05b035 100644 (file)
--- 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;
 }
 
index c6f1882ce2c9769a438cdb5ad901e1dc8d95bab7..2395b461afaedf1548b001cd3e27e38f36e35bc1 100644 (file)
@@ -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;
+}
index dfb705a5fb0fafb54d1abb3abc44344ad7cd41f5..95caa33deb4c7c6875113cb89d20f04ca2dbcf56 100644 (file)
@@ -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