]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Implement RFC 5929 tls-unique channel binding.
authorSimon Josefsson <simon@josefsson.org>
Fri, 15 Oct 2010 12:37:36 +0000 (14:37 +0200)
committerSimon Josefsson <simon@josefsson.org>
Fri, 15 Oct 2010 12:37:36 +0000 (14:37 +0200)
lib/gnutls_handshake.c
lib/gnutls_int.h
lib/gnutls_state.c
src/common.c

index 20b06c4c3091bea9f18050675a8768b561bdf5d7..e88b876f9d25e491eab466a78982874b23b786c3 100644 (file)
@@ -710,6 +710,18 @@ _gnutls_send_finished (gnutls_session_t session, int again)
          return ret;
        }
 
+      if ((session->internals.resumed == RESUME_FALSE
+          && session->security_parameters.entity == GNUTLS_CLIENT)
+         || (session->internals.resumed == RESUME_TRUE
+             && session->security_parameters.entity == GNUTLS_SERVER))
+       {
+         /* if we are a client not resuming - or we are a server resuming */
+         _gnutls_handshake_log ("HSK[%p]: recording tls-unique CB (send)\n",
+                                session);
+         memcpy (session->internals.cb_tls_unique, data, vdata_size);
+         session->internals.cb_tls_unique_len = vdata_size;
+       }
+
       ret =
        _gnutls_send_handshake (session, bufel, GNUTLS_HANDSHAKE_FINISHED);
     }
@@ -795,6 +807,18 @@ _gnutls_recv_finished (gnutls_session_t session)
       return ret;
     }
 
+  if ((session->internals.resumed == RESUME_TRUE
+       && session->security_parameters.entity == GNUTLS_CLIENT)
+      || (session->internals.resumed == RESUME_FALSE
+         && session->security_parameters.entity == GNUTLS_SERVER))
+    {
+      /* if we are a client resuming - or we are a server not resuming */
+      _gnutls_handshake_log ("HSK[%p]: recording tls-unique CB (recv)\n",
+                            session);
+      memcpy (session->internals.cb_tls_unique, data, data_size);
+      session->internals.cb_tls_unique_len = data_size;
+    }
+
   session->internals.initial_negotiation_completed = 1;
 
   return ret;
index 87d8f5ca11d3b3d54e3b8d91666040fee7788ae0..b97830e7295fd47a358608c2a1122b34719e6d45 100644 (file)
@@ -727,6 +727,9 @@ typedef struct
     int set:1;
   } resumed_extension_int_data[MAX_EXT_TYPES];
 
+  unsigned int cb_tls_unique_len;
+  unsigned char cb_tls_unique[MAX_VERIFY_DATA_SIZE];
+
   /* If you add anything here, check _gnutls_handshake_internal_state_clear().
    */
 } internals_st;
index 86e3c00ff41fff306c68fff4d46300070f804344..310e1432162028cb0c7db38e08fac4f59c3fabba 100644 (file)
@@ -1354,7 +1354,8 @@ gnutls_session_enable_compatibility_mode (gnutls_session_t session)
  * @cbtype: an #gnutls_channel_binding_t enumeration type
  * @cb: output buffer array with data
  *
- * Extract given channel binding data of the @cbtype type.
+ * Extract given channel binding data of the @cbtype (e.g.,
+ * %GNUTLS_CB_TLS_UNIQUE) type.
  *
  * Returns: %GNUTLS_E_SUCCESS on success,
  * %GNUTLS_E_UNIMPLEMENTED_FEATURE if the @cbtype is unsupported,
@@ -1368,5 +1369,18 @@ gnutls_session_channel_binding (gnutls_session_t session,
                                gnutls_channel_binding_t cbtype,
                                gnutls_datum_t *cb)
 {
-  return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+  if (cbtype != GNUTLS_CB_TLS_UNIQUE)
+    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+
+  if (!session->internals.initial_negotiation_completed)
+    return GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE;
+
+  cb->size = session->internals.cb_tls_unique_len;
+  cb->data = gnutls_malloc (cb->size);
+  if (cb->data == NULL)
+    return GNUTLS_E_MEMORY_ERROR;
+
+  memcpy (cb->data, session->internals.cb_tls_unique, cb->size);
+
+  return 0;
 }
index 51ba9465a636af22a016e64ff9bda7a89400c6bc..b270cd5f1f17bc596460f38e0e6202b1e0a7a574 100644 (file)
@@ -488,6 +488,23 @@ print_info (gnutls_session_t session, const char *hostname, int insecure)
       printf ("- Session ID: %s\n", raw_to_string (id, id_size));
     }
 
+  {
+    gnutls_datum cb;
+    int rc;
+
+    rc = gnutls_session_channel_binding (session, GNUTLS_CB_TLS_UNIQUE, &cb);
+    if (rc)
+       fprintf (stderr, "Channel binding error: %s\n", gnutls_strerror (rc));
+    else
+      {
+       size_t i;
+
+       printf ("- Channel binding 'tls-unique': ");
+       for (i = 0; i < cb.size; i++)
+         printf ("%02x", cb.data[i]);
+       printf ("\n");
+      }
+  }
 
   fflush (stdout);