]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
When resuming no extensions were parsed thus the safe
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 12 Jan 2010 19:17:07 +0000 (20:17 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Tue, 12 Jan 2010 19:17:07 +0000 (20:17 +0100)
renegotiation extension was ignored as well causing a
false detection of unsafe session. Corrected by making
a special class of extensions called RESUMED. Those are
parsed even when resuming (normally we don't do it to
prevent clients overwriting capabilities and credentials).

lib/gnutls_extensions.c
lib/gnutls_handshake.c
lib/includes/gnutls/gnutls.h.in
tests/resume.c

index 4e9db89e7c71ecb44f2ef9346dd1371632dbb463..2e8ad07f45b7be7ad337ff9d045e9b0be852a635 100644 (file)
@@ -324,7 +324,7 @@ _gnutls_ext_init (void)
 
   ret = gnutls_ext_register (GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
                             "SAFE_RENEGOTIATION",
-                            GNUTLS_EXT_TLS,
+                            GNUTLS_EXT_RESUMED,
                             _gnutls_safe_renegotiation_recv_params,
                             _gnutls_safe_renegotiation_send_params);
   if (ret != GNUTLS_E_SUCCESS)
index 983027876282a5f603eca6774cc00c1876b84fbf..3620a2991a28548c1a431db016cd2e42c658c68a 100644 (file)
@@ -450,6 +450,33 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
 
   if (ret == 0)
     {                          /* resumed! */
+      /* Parse only the safe renegotiation extension
+       * We don't want to parse any other extensions since
+       * we don't want new extension values to overwrite the
+       * resumed ones.
+       */
+       
+      /* move forward to extensions */
+      DECR_LEN (len, 2);
+      suite_size = _gnutls_read_uint16 (&data[pos]);
+      pos += 2;
+
+      DECR_LEN (len, suite_size);
+      pos += suite_size;
+      
+      DECR_LEN (len, 1);
+      comp_size = data[pos++]; /* z is the number of compression methods */
+      DECR_LEN (len, comp_size);
+      pos += comp_size;
+
+      ret = _gnutls_parse_extensions (session, GNUTLS_EXT_RESUMED,
+                                 &data[pos], len);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+          return ret;
+        }
+
       resume_copy_required_values (session);
       session->internals.resumed = RESUME_TRUE;
       
@@ -504,9 +531,16 @@ _gnutls_read_client_hello (gnutls_session_t session, opaque * data,
       return ret;
     }
 
+  ret = _gnutls_parse_extensions (session, GNUTLS_EXT_RESUMED,
+                                 &data[pos], len);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
   ret = _gnutls_parse_extensions (session, GNUTLS_EXT_TLS,
                                  &data[pos], len);
-  /* len is the rest of the parsed length */
   if (ret < 0)
     {
       gnutls_assert ();
@@ -1718,9 +1752,21 @@ _gnutls_read_server_hello (gnutls_session_t session,
    */
   if (_gnutls_client_check_if_resuming
       (session, &data[pos], session_id_len) == 0)
-    return 0;
-  pos += session_id_len;
+    {
+      pos += session_id_len + 2 + 1;
+      DECR_LEN (len, 2+1);
+
+      ret = _gnutls_parse_extensions (session, GNUTLS_EXT_RESUMED,
+                                 &data[pos], len);
+      if (ret < 0)
+        {
+          gnutls_assert ();
+          return ret;
+        }
+      return 0;
+    }
 
+  pos += session_id_len;
 
   /* Check if the given cipher suite is supported and copy
    * it to the session.
@@ -1752,7 +1798,6 @@ _gnutls_read_server_hello (gnutls_session_t session,
    */
   ret = _gnutls_parse_extensions (session, GNUTLS_EXT_ANY,
                                  &data[pos], len);
-  /* len is the rest of the parsed length */
   if (ret < 0)
     {
       gnutls_assert ();
index cbcf49333284d9e603b3e2294f15483c23c07490..ea691e666705f5efd6bc7baf6f9a7e0145fa4cb4 100644 (file)
@@ -511,7 +511,8 @@ extern "C" {
     {
       GNUTLS_EXT_ANY,
       GNUTLS_EXT_APPLICATION,
-      GNUTLS_EXT_TLS
+      GNUTLS_EXT_TLS,
+      GNUTLS_EXT_RESUMED, /* parse even if resuming */
     } gnutls_ext_parse_type_t;
 
   int gnutls_ext_register (int type,
index c52c1d6bed58c4e5c88173b9a8988d1fe1c90efc..80a4c7d82e8404a9fdbe81d21a58dc5459f51f04 100644 (file)
@@ -58,6 +58,8 @@ struct params_res
   int expect_resume;
 };
 
+pid_t child;
+
 struct params_res resume_tests[] = {
   {"try to resume from db", 50, 0, 0, 1},
 #ifdef ENABLE_SESSION_TICKET
@@ -74,6 +76,12 @@ struct params_res resume_tests[] = {
 #define MAX_BUF 1024
 #define MSG "Hello TLS"
 
+static void
+tls_log_func (int level, const char *str)
+{
+  fprintf (stderr, "%s |<%d>| %s", child ? "server" : "client", level, str);
+}
+
 static void
 client (struct params_res *params)
 {
@@ -89,6 +97,11 @@ client (struct params_res *params)
   int t;
   gnutls_datum_t session_data;
 
+  if (debug)
+    {
+      gnutls_global_set_log_function (tls_log_func);
+      gnutls_global_set_log_level (4);
+    }
   gnutls_global_init ();
 
   gnutls_anon_allocate_client_credentials (&anoncred);
@@ -336,8 +349,13 @@ server (struct params_res *params)
 
   /* this must be called once in the program, it is mostly for the server.
    */
-  gnutls_global_init ();
+  if (debug)
+    {
+      gnutls_global_set_log_function (tls_log_func);
+      gnutls_global_set_log_level (4);
+    }
 
+  gnutls_global_init ();
   gnutls_anon_allocate_server_credentials (&anoncred);
 
   success ("Launched, generating DH parameters...\n");
@@ -430,7 +448,6 @@ server (struct params_res *params)
 void
 doit (void)
 {
-  pid_t child;
   int i;
 
   for (i = 0; resume_tests[i].desc; i++)