gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_2_9_7-15-g9553b32


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_2_9_7-15-g9553b32
Date: Thu, 22 Oct 2009 21:11:34 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=9553b32ffc4a0facaec4fa087ba56909bb939e8c

The branch, master has been updated
       via  9553b32ffc4a0facaec4fa087ba56909bb939e8c (commit)
      from  4f214970374c474692dd18032246a14b2e3686c5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9553b32ffc4a0facaec4fa087ba56909bb939e8c
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Thu Oct 22 19:33:44 2009 +0300

    1. Fix for memory leaks on interrupted handshake.
    2. Fixes issue where a TLS 1.2 client will wrongly calculate hashes if the 
server will select a different than 1.2 protocol.
    
    3. In TLS 1.2 when a certificate request is sent, support is not complete. 
In that case abort the handshake. By checking
    TLS 1.2 it seems that the algorithms to be used for the signature in the 
certificate verify message are negotiated not at
    the client/server hello messages but rather selected by the server at the 
certificate request. This might not look as bad, but
    since in this message we have to sign all previous handshake messages, it 
forces us to keep all the handshake messages into a
    buffer until this point... I don't know who proposed this change to the TLS 
WG, but it seems it wasn't really thought of.

-----------------------------------------------------------------------

Summary of changes:
 lib/gnutls_buffers.c   |   20 ----
 lib/gnutls_buffers.h   |    2 -
 lib/gnutls_cipher.c    |   11 ++
 lib/gnutls_handshake.c |  292 +++++++++++++++++++++++++++++++-----------------
 lib/gnutls_handshake.h |    2 +
 lib/gnutls_hash_int.c  |   27 ++++-
 lib/gnutls_hash_int.h  |    1 +
 lib/gnutls_int.h       |   25 ++++-
 lib/gnutls_sig.c       |   23 +++-
 lib/gnutls_state.c     |   15 ++-
 10 files changed, 279 insertions(+), 139 deletions(-)

diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c
index 4e54df6..75c3287 100644
--- a/lib/gnutls_buffers.c
+++ b/lib/gnutls_buffers.c
@@ -1064,7 +1064,6 @@ _gnutls_handshake_buffer_put (gnutls_session_t session, 
opaque * data,
     }
 
   _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", (int)length);
-
   if (_gnutls_buffer_append (&session->internals.handshake_hash_buffer,
                             data, length) < 0)
     {
@@ -1086,24 +1085,6 @@ _gnutls_handshake_buffer_get_size (gnutls_session_t 
session)
  * and returns data from it (peek mode!)
  */
 int
-_gnutls_handshake_buffer_peek (gnutls_session_t session, opaque * data,
-                              size_t length)
-{
-  if (length > session->internals.handshake_hash_buffer.length)
-    {
-      length = session->internals.handshake_hash_buffer.length;
-    }
-
-  _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n", (int)length);
-
-  memcpy (data, session->internals.handshake_hash_buffer.data, length);
-  return length;
-}
-
-/* this function does not touch the buffer
- * and returns data from it (peek mode!)
- */
-int
 _gnutls_handshake_buffer_get_ptr (gnutls_session_t session,
                                  opaque ** data_ptr, size_t * length)
 {
@@ -1137,7 +1118,6 @@ _gnutls_handshake_buffer_clear (gnutls_session_t session)
 {
 
   _gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");
-
   _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
 
   return 0;
diff --git a/lib/gnutls_buffers.h b/lib/gnutls_buffers.h
index b21ac5b..a8ffa7d 100644
--- a/lib/gnutls_buffers.h
+++ b/lib/gnutls_buffers.h
@@ -41,8 +41,6 @@ ssize_t _gnutls_io_write_buffered2 (gnutls_session_t, const 
void *iptr,
                                    size_t n, const void *iptr2, size_t n2);
 
 int _gnutls_handshake_buffer_get_size (gnutls_session_t session);
-int _gnutls_handshake_buffer_peek (gnutls_session_t session, opaque * data,
-                                  size_t length);
 int _gnutls_handshake_buffer_put (gnutls_session_t session, opaque * data,
                                  size_t length);
 int _gnutls_handshake_buffer_clear (gnutls_session_t session);
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index 0d8c5e1..5f2ed62 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -418,6 +418,10 @@ _gnutls_compressed2ciphertext (gnutls_session_t session,
   return length;
 }
 
+#define DEINIT_MAC(td, ver, algo) \
+          if (algo != GNUTLS_MAC_NULL) \
+            mac_deinit (&td, NULL, ver);
+
 /* Deciphers the ciphertext packet, and puts the result to compress_data, of 
compress_size.
  * Returns the actual compressed packet size.
  */
@@ -473,6 +477,9 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
                                   ciphertext.size)) < 0)
        {
          gnutls_assert ();
+         DEINIT_MAC(td, ver, session->security_parameters.write_mac_algorithm);
+
+
          return ret;
        }
 
@@ -483,6 +490,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
       if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0))
        {
          gnutls_assert ();
+         DEINIT_MAC(td, ver, session->security_parameters.write_mac_algorithm);
          return GNUTLS_E_DECRYPTION_FAILED;
        }
 
@@ -492,6 +500,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
                                   ciphertext.size)) < 0)
        {
          gnutls_assert ();
+         DEINIT_MAC(td, ver, session->security_parameters.write_mac_algorithm);
          return ret;
        }
 
@@ -505,6 +514,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
          if (ciphertext.size == 0)
            {
              gnutls_assert ();
+              DEINIT_MAC(td, ver, 
session->security_parameters.write_mac_algorithm);
              return GNUTLS_E_DECRYPTION_FAILED;
            }
        }
@@ -537,6 +547,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
       break;
     default:
       gnutls_assert ();
+      DEINIT_MAC(td, ver, session->security_parameters.write_mac_algorithm);
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 83dc54e..93e0553 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -63,17 +63,31 @@
 #define TRUE 1
 #define FALSE 0
 
-int _gnutls_server_select_comp_method (gnutls_session_t session,
+static int _gnutls_handshake_hash_init (gnutls_session_t session);
+static int _gnutls_server_select_comp_method (gnutls_session_t session,
                                       opaque * data, int datalen);
+static int
+_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
+                                 gnutls_handshake_description_t recv_type,
+                                 opaque * header, uint16_t header_size,
+                                 opaque * dataptr, uint32_t datalen);
 
 
 /* Clears the handshake hash buffers and handles.
  */
-static void
+void
 _gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
 {
-  _gnutls_hash_deinit (&session->internals.handshake_mac_handle_md5, NULL);
-  _gnutls_hash_deinit (&session->internals.handshake_mac_handle_sha, NULL);
+  if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_10) 
+    {
+      _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls10.md5, 
NULL);
+      _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls10.sha, 
NULL);
+    }
+  else if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_12)
+    {
+      _gnutls_hash_deinit (&session->internals.handshake_mac_handle.tls12.mac, 
NULL);
+    }
+  session->security_parameters.handshake_mac_handle_type = 0;
   session->internals.handshake_mac_handle_init = 0;
   _gnutls_handshake_buffer_clear (session);
 }
@@ -150,23 +164,33 @@ _gnutls_ssl3_finished (gnutls_session_t session, int 
type, opaque * ret)
   const char *mesg;
   int rc;
 
-  rc =
-    _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5);
-  if (rc < 0)
+  if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_10) 
     {
-      gnutls_assert ();
-      return rc;
-    }
+      rc =
+        _gnutls_hash_copy (&td_md5, 
&session->internals.handshake_mac_handle.tls10.md5);
+      if (rc < 0)
+        {
+          gnutls_assert ();
+          return rc;
+        }
+
+      rc =
+        _gnutls_hash_copy (&td_sha, 
&session->internals.handshake_mac_handle.tls10.sha);
+      if (rc < 0)
+        {
+          gnutls_assert ();
+          _gnutls_hash_deinit (&td_md5, NULL);
+          return rc;
+        }
 
-  rc =
-    _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
-  if (rc < 0)
+    }
+  else
     {
-      gnutls_assert ();
-      _gnutls_hash_deinit (&td_md5, NULL);
-      return rc;
+      gnutls_assert();
+      return GNUTLS_E_INTERNAL_ERROR;
     }
 
+
   if (type == GNUTLS_SERVER)
     {
       mesg = SSL3_SERVER_MSG;
@@ -198,7 +222,7 @@ static int
 _gnutls_finished (gnutls_session_t session, int type, void *ret)
 {
   const int siz = TLS_MSG_LEN;
-  opaque concat[36];
+  opaque concat[MAX_HASH_SIZE+16/*MD5*/];
   size_t len;
   const char *mesg;
   digest_hd_st td_md5;
@@ -206,39 +230,45 @@ _gnutls_finished (gnutls_session_t session, int type, 
void *ret)
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
   int rc;
 
-  if (!_gnutls_version_has_selectable_prf(ver))
+  if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_10) 
     {
       rc =
        _gnutls_hash_copy (&td_md5,
-                          &session->internals.handshake_mac_handle_md5);
+                          &session->internals.handshake_mac_handle.tls10.md5);
       if (rc < 0)
        {
          gnutls_assert ();
          return rc;
        }
-    }
 
-  rc =
-    _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
-  if (rc < 0)
-    {
-      gnutls_assert ();
-      _gnutls_hash_deinit (&td_md5, NULL);
-      return rc;
-    }
+      rc =
+        _gnutls_hash_copy (&td_sha, 
&session->internals.handshake_mac_handle.tls10.sha);
+      if (rc < 0)
+        {
+          gnutls_assert ();
+          _gnutls_hash_deinit (&td_md5, NULL);
+          return rc;
+        }
 
-  if (!_gnutls_version_has_selectable_prf(ver))
-    {
-      _gnutls_hash_deinit (&td_md5, concat);
-      _gnutls_hash_deinit (&td_sha, &concat[16]);
-      len = 20 + 16;
+        _gnutls_hash_deinit (&td_md5, concat);
+        _gnutls_hash_deinit (&td_sha, &concat[16]);
+        len = 20 + 16;
     }
-  else
+  else if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_12) 
     {
-      _gnutls_hash_deinit (&td_sha, concat);
-      len = _gnutls_hash_get_algo_len (td_sha.algorithm);
+      rc =
+        _gnutls_hash_copy (&td_sha, 
&session->internals.handshake_mac_handle.tls12.mac);
+      if (rc < 0)
+        {
+          gnutls_assert ();
+          return rc;
+        }
+
+        _gnutls_hash_deinit (&td_sha, concat);
+        len = _gnutls_hash_get_algo_len (td_sha.algorithm);
     }
 
+
   if (type == GNUTLS_SERVER)
     {
       mesg = SERVER_MSG;
@@ -534,8 +564,15 @@ _gnutls_handshake_hash_pending (gnutls_session_t session)
 
   if (siz > 0)
     {
-      _gnutls_hash (&session->internals.handshake_mac_handle_sha, data, siz);
-      _gnutls_hash (&session->internals.handshake_mac_handle_md5, data, siz);
+      if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_10) 
+        {
+          _gnutls_hash (&session->internals.handshake_mac_handle.tls10.sha, 
data, siz);
+          _gnutls_hash (&session->internals.handshake_mac_handle.tls10.md5, 
data, siz);
+        } 
+      else if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_12)
+        {
+          _gnutls_hash (&session->internals.handshake_mac_handle.tls12.mac, 
data, siz);
+        }
     }
 
   _gnutls_handshake_buffer_empty (session);
@@ -836,7 +873,7 @@ finish:
 
 /* This selects the best supported compression method from the ones provided 
  */
-int
+static int
 _gnutls_server_select_comp_method (gnutls_session_t session,
                                   opaque * data, int datalen)
 {
@@ -915,6 +952,18 @@ _gnutls_handshake_hash_add_sent (gnutls_session_t session,
 {
   int ret;
 
+  if (session->security_parameters.entity == GNUTLS_CLIENT && type == 
GNUTLS_HANDSHAKE_CLIENT_HELLO)
+    {
+      /* do not hash immediatelly since the hash has not yet been initialized 
*/
+      if ((ret =
+          _gnutls_handshake_buffer_put (session, dataptr, datalen)) < 0)
+       {
+         gnutls_assert ();
+         return ret;
+       }
+      return 0;
+    }
+
   if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
     {
       gnutls_assert ();
@@ -923,10 +972,18 @@ _gnutls_handshake_hash_add_sent (gnutls_session_t session,
 
   if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
     {
-      _gnutls_hash (&session->internals.handshake_mac_handle_sha, dataptr,
+      if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_10) 
+        {
+          _gnutls_hash (&session->internals.handshake_mac_handle.tls10.sha, 
dataptr,
                    datalen);
-      _gnutls_hash (&session->internals.handshake_mac_handle_md5, dataptr,
+          _gnutls_hash (&session->internals.handshake_mac_handle.tls10.md5, 
dataptr,
                    datalen);
+        }
+      else if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_12) 
+        { 
+          _gnutls_hash (&session->internals.handshake_mac_handle.tls12.mac, 
dataptr,
+                   datalen);
+        }
     }
 
   return 0;
@@ -1165,11 +1222,14 @@ _gnutls_handshake_hash_add_recvd (gnutls_session_t 
session,
   /* The idea here is to hash the previous message we received,
    * and add the one we just received into the handshake_hash_buffer.
    */
-
-  if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
+  if ((session->security_parameters.entity == GNUTLS_SERVER || recv_type != 
GNUTLS_HANDSHAKE_SERVER_HELLO) && 
+      (session->security_parameters.entity == GNUTLS_CLIENT || recv_type != 
GNUTLS_HANDSHAKE_CLIENT_HELLO))
     {
-      gnutls_assert ();
-      return ret;
+      if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
+        {
+          gnutls_assert ();
+          return ret;
+        }
     }
 
   /* here we buffer the handshake messages - needed at Finished message */
@@ -1292,11 +1352,23 @@ _gnutls_recv_handshake (gnutls_session_t session, 
uint8_t ** data,
     case GNUTLS_HANDSHAKE_CLIENT_HELLO:
     case GNUTLS_HANDSHAKE_SERVER_HELLO:
       ret = _gnutls_recv_hello (session, dataptr, length32);
+      
       /* dataptr is freed because the caller does not
        * need it */
       gnutls_free (dataptr);
       if (data != NULL)
        *data = NULL;
+      
+      if (ret < 0)
+        break;
+
+      /* initialize the hashes for both - (client will know server's version
+       * and server as well at this point) */
+      if ((ret = _gnutls_handshake_hash_init (session)) < 0) {
+        gnutls_assert();
+        return ret;
+      }
+
       break;
     case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
       if (length32 == 0)
@@ -2167,38 +2239,60 @@ _gnutls_abort_handshake (gnutls_session_t session, int 
ret)
 /* This function initialized the handshake hash session.
  * required for finished messages.
  */
-inline static int
+static int
 _gnutls_handshake_hash_init (gnutls_session_t session)
 {
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
-  gnutls_digest_algorithm_t hash_algo = GNUTLS_MAC_SHA1;
 
   if (session->internals.handshake_mac_handle_init == 0)
     {
-      int ret =
-       _gnutls_hash_init (&session->internals.handshake_mac_handle_md5,
+      int ret;
+
+      /* set the hash type for handshake message hashing */
+      if (_gnutls_version_has_selectable_prf (ver))
+        session->security_parameters.handshake_mac_handle_type = 
HANDSHAKE_MAC_TYPE_12;
+      else
+        session->security_parameters.handshake_mac_handle_type = 
HANDSHAKE_MAC_TYPE_10;
+
+
+      if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_10) 
+        {
+          ret =
+           _gnutls_hash_init 
(&session->internals.handshake_mac_handle.tls10.md5,
                           GNUTLS_MAC_MD5);
 
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return ret;
-       }
+          if (ret < 0)
+           {
+             gnutls_assert ();
+             return ret;
+           }
 
-      /* The algorithm to compute hash over handshake messages must be
-        same as the one used as the basis for PRF.  By now we use
-        SHA256. */
-      if (_gnutls_version_has_selectable_prf (ver))
-       hash_algo = GNUTLS_MAC_SHA256;
+          ret =
+            _gnutls_hash_init 
(&session->internals.handshake_mac_handle.tls10.sha,
+                          GNUTLS_MAC_SHA1);
+          if (ret < 0)
+           {
+             gnutls_assert ();
+             _gnutls_hash_deinit 
(&session->internals.handshake_mac_handle.tls10.md5, NULL);
+             return GNUTLS_E_MEMORY_ERROR;
+           }
+        }
+      else if (session->security_parameters.handshake_mac_handle_type == 
HANDSHAKE_MAC_TYPE_12)
+        {
+        /* The algorithm to compute hash over handshake messages must be
+          same as the one used as the basis for PRF.  By now we use
+          SHA256. */
+          gnutls_digest_algorithm_t hash_algo = GNUTLS_MAC_SHA256;
 
-      ret =
-       _gnutls_hash_init (&session->internals.handshake_mac_handle_sha,
+          ret =
+           _gnutls_hash_init 
(&session->internals.handshake_mac_handle.tls12.mac,
                           hash_algo);
-      if (ret < 0)
-       {
-         gnutls_assert ();
-         return GNUTLS_E_MEMORY_ERROR;
-       }
+           if (ret < 0)
+            {
+              gnutls_assert ();
+              return GNUTLS_E_MEMORY_ERROR;
+            }
+        }
 
       session->internals.handshake_mac_handle_init = 1;
     }
@@ -2300,12 +2394,6 @@ gnutls_handshake (gnutls_session_t session)
 {
   int ret;
 
-  if ((ret = _gnutls_handshake_hash_init (session)) < 0)
-    {
-      gnutls_assert ();
-      return ret;
-    }
-
   if (session->security_parameters.entity == GNUTLS_CLIENT)
     {
       ret = _gnutls_handshake_client (session);
@@ -2343,9 +2431,9 @@ gnutls_handshake (gnutls_session_t session)
   return 0;
 }
 
-#define IMED_RET( str, ret) do { \
+#define IMED_RET( str, ret, check_fatal) do { \
        if (ret < 0) { \
-               if (gnutls_error_is_fatal(ret)==0) return ret; \
+               if (check_fatal != 0 && gnutls_error_is_fatal(ret)==0) return 
ret; \
                gnutls_assert(); \
                ERR( str, ret); \
                _gnutls_handshake_hash_buffers_clear(session); \
@@ -2383,7 +2471,7 @@ _gnutls_handshake_client (gnutls_session_t session)
     case STATE1:
       ret = _gnutls_send_hello (session, AGAIN (STATE1));
       STATE = STATE1;
-      IMED_RET ("send hello", ret);
+      IMED_RET ("send hello", ret, 0);
 
     case STATE2:
       /* receive the server hello */
@@ -2392,14 +2480,14 @@ _gnutls_handshake_client (gnutls_session_t session)
                                GNUTLS_HANDSHAKE_SERVER_HELLO,
                                MANDATORY_PACKET);
       STATE = STATE2;
-      IMED_RET ("recv hello", ret);
+      IMED_RET ("recv hello", ret, 1);
 
     case STATE70:
       if (session->security_parameters.extensions.do_recv_supplemental)
        {
          ret = _gnutls_recv_supplemental (session);
          STATE = STATE70;
-         IMED_RET ("recv supplemental", ret);
+         IMED_RET ("recv supplemental", ret, 1);
        }
 
     case STATE3:
@@ -2407,14 +2495,14 @@ _gnutls_handshake_client (gnutls_session_t session)
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_recv_server_certificate (session);
       STATE = STATE3;
-      IMED_RET ("recv server certificate", ret);
+      IMED_RET ("recv server certificate", ret, 1);
 
     case STATE4:
       /* receive the server key exchange */
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_recv_server_kx_message (session);
       STATE = STATE4;
-      IMED_RET ("recv server kx message", ret);
+      IMED_RET ("recv server kx message", ret, 1);
 
     case STATE5:
       /* receive the server certificate request - if any 
@@ -2423,7 +2511,7 @@ _gnutls_handshake_client (gnutls_session_t session)
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_recv_server_certificate_request (session);
       STATE = STATE5;
-      IMED_RET ("recv server certificate request message", ret);
+      IMED_RET ("recv server certificate request message", ret, 1);
 
     case STATE6:
       /* receive the server hello done */
@@ -2433,14 +2521,14 @@ _gnutls_handshake_client (gnutls_session_t session)
                                  GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
                                  MANDATORY_PACKET);
       STATE = STATE6;
-      IMED_RET ("recv server hello done", ret);
+      IMED_RET ("recv server hello done", ret, 1);
 
     case STATE71:
       if (session->security_parameters.extensions.do_send_supplemental)
        {
          ret = _gnutls_send_supplemental (session, AGAIN (STATE71));
          STATE = STATE71;
-         IMED_RET ("send supplemental", ret);
+         IMED_RET ("send supplemental", ret, 0);
        }
 
     case STATE7:
@@ -2449,13 +2537,13 @@ _gnutls_handshake_client (gnutls_session_t session)
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_send_client_certificate (session, AGAIN (STATE7));
       STATE = STATE7;
-      IMED_RET ("send client certificate", ret);
+      IMED_RET ("send client certificate", ret, 0);
 
     case STATE8:
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_send_client_kx_message (session, AGAIN (STATE8));
       STATE = STATE8;
-      IMED_RET ("send client kx", ret);
+      IMED_RET ("send client kx", ret, 0);
 
     case STATE9:
       /* send client certificate verify */
@@ -2463,7 +2551,7 @@ _gnutls_handshake_client (gnutls_session_t session)
        ret =
          _gnutls_send_client_certificate_verify (session, AGAIN (STATE9));
       STATE = STATE9;
-      IMED_RET ("send client certificate verify", ret);
+      IMED_RET ("send client certificate verify", ret, 0);
 
       STATE = STATE0;
     default:
@@ -2612,19 +2700,19 @@ _gnutls_handshake_server (gnutls_session_t session)
                                GNUTLS_HANDSHAKE_CLIENT_HELLO,
                                MANDATORY_PACKET);
       STATE = STATE1;
-      IMED_RET ("recv hello", ret);
+      IMED_RET ("recv hello", ret, 1);
 
     case STATE2:
       ret = _gnutls_send_hello (session, AGAIN (STATE2));
       STATE = STATE2;
-      IMED_RET ("send hello", ret);
+      IMED_RET ("send hello", ret, 0);
 
     case STATE70:
       if (session->security_parameters.extensions.do_send_supplemental)
        {
          ret = _gnutls_send_supplemental (session, AGAIN (STATE70));
          STATE = STATE70;
-         IMED_RET ("send supplemental data", ret);
+         IMED_RET ("send supplemental data", ret, 0);
        }
 
       /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
@@ -2634,14 +2722,14 @@ _gnutls_handshake_server (gnutls_session_t session)
       if (session->internals.resumed == RESUME_FALSE)
        ret = _gnutls_send_server_certificate (session, AGAIN (STATE3));
       STATE = STATE3;
-      IMED_RET ("send server certificate", ret);
+      IMED_RET ("send server certificate", ret, 0);
 
     case STATE4:
       /* send server key exchange (A) */
       if (session->internals.resumed == RESUME_FALSE)
        ret = _gnutls_send_server_kx_message (session, AGAIN (STATE4));
       STATE = STATE4;
-      IMED_RET ("send server kx", ret);
+      IMED_RET ("send server kx", ret, 0);
 
     case STATE5:
       /* Send certificate request - if requested to */
@@ -2649,7 +2737,7 @@ _gnutls_handshake_server (gnutls_session_t session)
        ret =
          _gnutls_send_server_certificate_request (session, AGAIN (STATE5));
       STATE = STATE5;
-      IMED_RET ("send server cert request", ret);
+      IMED_RET ("send server cert request", ret, 0);
 
     case STATE6:
       /* send the server hello done */
@@ -2659,14 +2747,14 @@ _gnutls_handshake_server (gnutls_session_t session)
                                        GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
                                        AGAIN (STATE6));
       STATE = STATE6;
-      IMED_RET ("send server hello done", ret);
+      IMED_RET ("send server hello done", ret, 0);
 
     case STATE71:
       if (session->security_parameters.extensions.do_recv_supplemental)
        {
          ret = _gnutls_recv_supplemental (session);
          STATE = STATE71;
-         IMED_RET ("recv client supplemental", ret);
+         IMED_RET ("recv client supplemental", ret, 1);
        }
 
       /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
@@ -2675,21 +2763,21 @@ _gnutls_handshake_server (gnutls_session_t session)
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_recv_client_certificate (session);
       STATE = STATE7;
-      IMED_RET ("recv client certificate", ret);
+      IMED_RET ("recv client certificate", ret, 1);
 
     case STATE8:
       /* receive the client key exchange message */
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_recv_client_kx_message (session);
       STATE = STATE8;
-      IMED_RET ("recv client kx", ret);
+      IMED_RET ("recv client kx", ret, 1);
 
     case STATE9:
       /* receive the client certificate verify message */
       if (session->internals.resumed == RESUME_FALSE)  /* if we are not 
resuming */
        ret = _gnutls_recv_client_certificate_verify_message (session);
       STATE = STATE9;
-      IMED_RET ("recv client certificate verify", ret);
+      IMED_RET ("recv client certificate verify", ret, 1);
 
       STATE = STATE0;          /* finished thus clear session */
     default:
@@ -2713,7 +2801,7 @@ _gnutls_handshake_common (gnutls_session_t session)
       /* if we are a client resuming - or we are a server not resuming */
 
       ret = _gnutls_recv_handshake_final (session, TRUE);
-      IMED_RET ("recv handshake final", ret);
+      IMED_RET ("recv handshake final", ret, 1);
 
 #ifdef ENABLE_SESSION_TICKET
       switch (STATE)
@@ -2724,7 +2812,7 @@ _gnutls_handshake_common (gnutls_session_t session)
            {
              ret = _gnutls_send_new_session_ticket (session, AGAIN(STATE40));
              STATE = STATE40;
-             IMED_RET ("send handshake new session ticket", ret);
+             IMED_RET ("send handshake new session ticket", ret, 0);
            }
          STATE = STATE0;
        default:
@@ -2733,13 +2821,13 @@ _gnutls_handshake_common (gnutls_session_t session)
 #endif
 
       ret = _gnutls_send_handshake_final (session, FALSE);
-      IMED_RET ("send handshake final", ret);
+      IMED_RET ("send handshake final", ret, 0);
     }
   else
     {                          /* if we are a client not resuming - or we are 
a server resuming */
 
       ret = _gnutls_send_handshake_final (session, TRUE);
-      IMED_RET ("send handshake final 2", ret);
+      IMED_RET ("send handshake final 2", ret, 0);
 
 #ifdef ENABLE_SESSION_TICKET
       switch (STATE)
@@ -2750,7 +2838,7 @@ _gnutls_handshake_common (gnutls_session_t session)
            {
              ret = _gnutls_recv_new_session_ticket (session);
              STATE = STATE41;
-             IMED_RET ("recv handshake new session ticket", ret);
+             IMED_RET ("recv handshake new session ticket", ret, 1);
            }
          STATE = STATE0;
        default:
@@ -2759,7 +2847,7 @@ _gnutls_handshake_common (gnutls_session_t session)
 #endif
 
       ret = _gnutls_recv_handshake_final (session, FALSE);
-      IMED_RET ("recv handshake final 2", ret);
+      IMED_RET ("recv handshake final 2", ret, 1);
     }
 
   if (session->security_parameters.entity == GNUTLS_SERVER)
diff --git a/lib/gnutls_handshake.h b/lib/gnutls_handshake.h
index f1b1bd6..2f484f5 100644
--- a/lib/gnutls_handshake.h
+++ b/lib/gnutls_handshake.h
@@ -55,6 +55,8 @@ int _gnutls_negotiate_version (gnutls_session_t session,
 int _gnutls_user_hello_func (gnutls_session_t session,
                             gnutls_protocol_t adv_version);
 
+void _gnutls_handshake_hash_buffers_clear (gnutls_session_t session);
+
 #define STATE session->internals.handshake_state
 /* This returns true if we have got there
  * before (and not finished due to an interrupt).
diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c
index e55ae54..5e5b2aa 100644
--- a/lib/gnutls_hash_int.c
+++ b/lib/gnutls_hash_int.c
@@ -77,6 +77,7 @@ _gnutls_hash_init (digest_hd_st * dig, 
gnutls_digest_algorithm_t algorithm)
          gnutls_assert ();
          return GNUTLS_E_HASH_FAILED;
        }
+      dig->active = 1;
       return 0;
     }
 
@@ -89,6 +90,7 @@ _gnutls_hash_init (digest_hd_st * dig, 
gnutls_digest_algorithm_t algorithm)
       return result;
     }
 
+  dig->active = 1;
   return 0;
 }
 
@@ -119,10 +121,10 @@ _gnutls_hash_copy (digest_hd_st * dst, digest_hd_st * src)
 {
   int result;
 
+  memset(dst, 0, sizeof(*dst));
   dst->algorithm = src->algorithm;
-  dst->key = NULL;             /* it's a hash anyway */
-  dst->keysize = 0;
   dst->registered = src->registered;
+  dst->active = 1;
 
   if (src->registered)
     {
@@ -165,7 +167,14 @@ _gnutls_hash_output (digest_hd_st * handle, void *digest)
 void
 _gnutls_hash_deinit (digest_hd_st * handle, void *digest)
 {
-  _gnutls_hash_output (handle, digest);
+  if (handle->active != 1) {
+    return;
+  }
+
+  if (digest != NULL)
+    _gnutls_hash_output (handle, digest);
+
+  handle->active = 0;
 
   if (handle->registered && handle->hd.rh.ctx != NULL)
     {
@@ -269,6 +278,7 @@ _gnutls_hmac_init (digest_hd_st * dig, 
gnutls_mac_algorithm_t algorithm,
          return GNUTLS_E_HASH_FAILED;
        }
 
+      dig->active = 1;
       return 0;
     }
 
@@ -283,6 +293,7 @@ _gnutls_hmac_init (digest_hd_st * dig, 
gnutls_mac_algorithm_t algorithm,
 
   _gnutls_mac_ops.setkey (dig->hd.gc, key, keylen);
 
+  dig->active = 1;
   return 0;
 }
 
@@ -323,8 +334,14 @@ _gnutls_hmac_output (digest_hd_st * handle, void *digest)
 void
 _gnutls_hmac_deinit (digest_hd_st * handle, void *digest)
 {
-  _gnutls_hmac_output (handle, digest);
+  if (handle->active != 1) {
+    return;
+  }
+
+  if (digest)
+    _gnutls_hmac_output (handle, digest);
 
+  handle->active = 0;
   if (handle->registered && handle->hd.rh.ctx != NULL)
     {
       handle->hd.rh.cc->deinit (handle->hd.rh.ctx);
@@ -398,6 +415,7 @@ _gnutls_mac_deinit_ssl3 (digest_hd_st * handle, void 
*digest)
   if (padsize == 0)
     {
       gnutls_assert ();
+      _gnutls_hash_deinit (handle, NULL);
       return;
     }
 
@@ -407,6 +425,7 @@ _gnutls_mac_deinit_ssl3 (digest_hd_st * handle, void 
*digest)
   if (rc < 0)
     {
       gnutls_assert ();
+      _gnutls_hash_deinit (handle, NULL);
       return;
     }
 
diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h
index 8017d12..d915af5 100644
--- a/lib/gnutls_hash_int.h
+++ b/lib/gnutls_hash_int.h
@@ -52,6 +52,7 @@ typedef struct
   gnutls_mac_algorithm_t algorithm;
   const void *key;
   int keysize;
+  int active;
 } digest_hd_st;
 
 int _gnutls_hmac_init (digest_hd_st*, gnutls_mac_algorithm_t algorithm,
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 100ad37..ac1da9d 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -200,6 +200,12 @@ typedef enum content_type_t
 #define GNUTLS_PK_ANY (gnutls_pk_algorithm_t)-1
 #define GNUTLS_PK_NONE (gnutls_pk_algorithm_t)-2
 
+typedef enum
+{
+  HANDSHAKE_MAC_TYPE_10=1,
+  HANDSHAKE_MAC_TYPE_12
+} handshake_mac_type_t;
+
 /* Store & Retrieve functions defines: 
  */
 
@@ -213,7 +219,6 @@ typedef struct auth_cred_st
   struct auth_cred_st *next;
 } auth_cred_st;
 
-
 struct gnutls_key_st
 {
   /* For DH KX */
@@ -361,6 +366,7 @@ typedef struct
   gnutls_cipher_algorithm_t write_bulk_cipher_algorithm;
   gnutls_mac_algorithm_t write_mac_algorithm;
   gnutls_compression_method_t write_compression_algorithm;
+  handshake_mac_type_t handshake_mac_handle_type; /* one of HANDSHAKE_TYPE_10 
and HANDSHAKE_TYPE_12 */
 
   /* this is the ciphersuite we are going to use 
    * moved here from internals in order to be restored
@@ -468,14 +474,25 @@ typedef struct
   gnutls_handshake_description_t recv_type;
 } handshake_header_buffer_st;
 
+
 typedef struct
 {
   gnutls_buffer application_data_buffer;       /* holds data to be delivered 
to application layer */
   gnutls_buffer handshake_hash_buffer; /* used to keep the last received 
handshake 
                                         * message */
-  digest_hd_st handshake_mac_handle_sha;       /* hash of the handshake 
messages */
-  digest_hd_st handshake_mac_handle_md5;       /* hash of the handshake 
messages */
-  int handshake_mac_handle_init; /* 1 when the previous two were initialized */
+  union
+    {
+      struct 
+        {
+          digest_hd_st sha;    /* hash of the handshake messages */
+          digest_hd_st md5;    /* hash of the handshake messages */
+        } tls10;
+      struct
+        {
+          digest_hd_st mac;    /* hash of the handshake messages for TLS 1.2+ 
*/
+        } tls12;
+    } handshake_mac_handle;
+  int handshake_mac_handle_init; /* 1 when the previous union and type were 
initialized */
 
   gnutls_buffer handshake_data_buffer; /* this is a buffer that holds the 
current handshake message */
   gnutls_buffer ia_data_buffer;        /* holds inner application data 
(TLS/IA) */
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 04d6154..c49f2ed 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -132,8 +132,17 @@ _gnutls_tls_sign_hdata (gnutls_session_t session,
   digest_hd_st td_sha;
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
+  /* FIXME: This is not compliant to TLS 1.2. We should use an algorithm from 
the
+   * SignatureAndHashAlgorithm field of Certificate Request.
+   */
+  if (session->security_parameters.handshake_mac_handle_type != 
HANDSHAKE_MAC_TYPE_10)
+    {
+      gnutls_assert();
+      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+    }
+  
   ret =
-    _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
+    _gnutls_hash_copy (&td_sha, 
&session->internals.handshake_mac_handle.tls10.sha);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -161,7 +170,7 @@ _gnutls_tls_sign_hdata (gnutls_session_t session,
     case GNUTLS_PK_RSA:
       ret =
        _gnutls_hash_copy (&td_md5,
-                          &session->internals.handshake_mac_handle_md5);
+                          &session->internals.handshake_mac_handle.tls10.md5);
       if (ret < 0)
        {
          gnutls_assert ();
@@ -464,8 +473,14 @@ _gnutls_verify_sig_hdata (gnutls_session_t session, 
gnutls_cert * cert,
   gnutls_datum_t dconcat;
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
+  if (session->security_parameters.handshake_mac_handle_type != 
HANDSHAKE_MAC_TYPE_10)
+    {
+      gnutls_assert();
+      return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+    }
+
   ret =
-    _gnutls_hash_copy (&td_md5, &session->internals.handshake_mac_handle_md5);
+    _gnutls_hash_copy (&td_md5, 
&session->internals.handshake_mac_handle.tls10.md5);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -473,7 +488,7 @@ _gnutls_verify_sig_hdata (gnutls_session_t session, 
gnutls_cert * cert,
     }
 
   ret =
-    _gnutls_hash_copy (&td_sha, &session->internals.handshake_mac_handle_sha);
+    _gnutls_hash_copy (&td_sha, 
&session->internals.handshake_mac_handle.tls10.sha);
   if (ret < 0)
     {
       gnutls_assert ();
diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c
index fede2a0..cd08f44 100644
--- a/lib/gnutls_state.c
+++ b/lib/gnutls_state.c
@@ -201,6 +201,8 @@ deinit_internal_params (gnutls_session_t session)
   if (session->internals.params.free_rsa_params)
     gnutls_rsa_params_deinit (session->internals.params.rsa_params);
 
+  _gnutls_handshake_hash_buffers_clear(session);
+
   memset (&session->internals.params, 0, sizeof (session->internals.params));
 }
 
@@ -208,8 +210,8 @@ deinit_internal_params (gnutls_session_t session)
  * structure within the session, which depend on the current handshake.
  * This is used to allow further handshakes.
  */
-void
-_gnutls_handshake_internal_state_clear (gnutls_session_t session)
+static void
+_gnutls_handshake_internal_state_init (gnutls_session_t session)
 {
   session->internals.extensions_sent_size = 0;
 
@@ -231,6 +233,13 @@ _gnutls_handshake_internal_state_clear (gnutls_session_t 
session)
   session->internals.last_handshake_out = -1;
 
   session->internals.resumable = RESUME_TRUE;
+}
+
+void
+_gnutls_handshake_internal_state_clear (gnutls_session_t session)
+{
+  _gnutls_handshake_internal_state_init(session);
+
   _gnutls_free_datum (&session->internals.recv_buffer);
 
   deinit_internal_params (session);
@@ -336,7 +345,7 @@ gnutls_init (gnutls_session_t * session, 
gnutls_connection_end_t con_end)
    * as NULL or 0. This is why calloc is used.
    */
 
-  _gnutls_handshake_internal_state_clear (*session);
+  _gnutls_handshake_internal_state_init (*session);
 
   return 0;
 }


hooks/post-receive
-- 
GNU gnutls




reply via email to

[Prev in Thread] Current Thread [Next in Thread]