]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Fix GNUTLS-SA-2008-1 security vulnerabilities.
authorSimon Josefsson <simon@josefsson.org>
Mon, 19 May 2008 08:34:08 +0000 (10:34 +0200)
committerSimon Josefsson <simon@josefsson.org>
Mon, 19 May 2008 12:05:37 +0000 (14:05 +0200)
See http://www.gnu.org/software/gnutls/security.html for updates.

lib/ext_server_name.c
lib/gnutls_cipher.c
lib/gnutls_handshake.c

index 72e42ffb9f1eb40b40f597090a16478268f9f2b1..a2db94939ffb20a8cbc1b5b2af9cf27617c268bf 100644 (file)
@@ -74,10 +74,27 @@ _gnutls_server_name_recv_params (gnutls_session_t session,
          len = _gnutls_read_uint16 (p);
          p += 2;
 
-         DECR_LENGTH_RET (data_size, len, 0);
-         server_names++;
+         if (len > 0)
+           {
+             DECR_LENGTH_RET (data_size, len, 0);
+             server_names++;
+             p += len;
+           }
+         else
+           _gnutls_handshake_log
+             ("HSK[%x]: Received zero size server name (under attack?)\n",
+              session);
 
-         p += len;
+       }
+
+      /* we cannot accept more server names.
+       */
+      if (server_names > MAX_SERVER_NAME_EXTENSIONS)
+       {
+         _gnutls_handshake_log
+           ("HSK[%x]: Too many server names received (under attack?)\n",
+            session);
+         server_names = MAX_SERVER_NAME_EXTENSIONS;
        }
 
       session->security_parameters.extensions.server_names_size =
@@ -85,10 +102,6 @@ _gnutls_server_name_recv_params (gnutls_session_t session,
       if (server_names == 0)
        return 0;               /* no names found */
 
-      /* we cannot accept more server names.
-       */
-      if (server_names > MAX_SERVER_NAME_EXTENSIONS)
-       server_names = MAX_SERVER_NAME_EXTENSIONS;
 
       p = data + 2;
       for (i = 0; i < server_names; i++)
index ad192f46bd09649cf3d6c59966796204768cce2e..778402aaf5124c827042bdbee8f7ed10f83cd835 100644 (file)
@@ -459,6 +459,14 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
       return GNUTLS_E_INTERNAL_ERROR;
     }
 
+  if (ciphertext.size < (unsigned) blocksize + hash_size)
+    {
+      _gnutls_record_log
+       ("REC[%x]: Short record length %d < %d + %d (under attack?)\n",
+        session, ciphertext.size, blocksize, hash_size);
+      gnutls_assert ();
+      return GNUTLS_E_DECRYPTION_FAILED;
+    }
 
   /* actual decryption (inplace)
    */
@@ -510,9 +518,7 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
 
       pad = ciphertext.data[ciphertext.size - 1] + 1;  /* pad */
 
-      length = ciphertext.size - hash_size - pad;
-
-      if (pad > ciphertext.size - hash_size)
+      if ((int)pad > (int)ciphertext.size - hash_size)
        {
          gnutls_assert ();
          /* We do not fail here. We check below for the
@@ -521,6 +527,8 @@ _gnutls_ciphertext2compressed (gnutls_session_t session,
          pad_failed = GNUTLS_E_DECRYPTION_FAILED;
        }
 
+      length = ciphertext.size - hash_size - pad;
+
       /* Check the pading bytes (TLS 1.x)
        */
       if (ver >= GNUTLS_TLS1 && pad_failed == 0)
index 4ab6db6d836326c7a19aa3a0b617fe70ff3d2370..d7981802a0bbd1d8895114af8641eb95ea7d0b94 100644 (file)
@@ -1003,6 +1003,14 @@ _gnutls_recv_handshake_header (gnutls_session_t session,
 
       *recv_type = session->internals.handshake_header_buffer.recv_type;
 
+      if (*recv_type != type)
+       {
+         gnutls_assert ();
+         _gnutls_handshake_log
+           ("HSK[%x]: Handshake type mismatch (under attack?)\n", session);
+         return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
+       }
+
       return session->internals.handshake_header_buffer.packet_length;
     }