summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2008-05-19 10:34:08 +0200
committerSimon Josefsson <simon@josefsson.org>2008-05-19 10:34:08 +0200
commita05a837a1c2225931c282ed9ba38d557ee8ad8b2 (patch)
tree4b7f83b6d6b5006859955c64c59a70929c16ac8e
parentfb9415218315c3ee3e04769f558bf2d15cceaa57 (diff)
downloadgnutls-a05a837a1c2225931c282ed9ba38d557ee8ad8b2.tar.gz
Fix GNUTLS-SA-2008-1 security vulnerabilities.
See http://www.gnu.org/software/gnutls/security.html for updates.
-rw-r--r--lib/ext_server_name.c27
-rw-r--r--lib/gnutls_cipher.c14
-rw-r--r--lib/gnutls_handshake.c8
3 files changed, 39 insertions, 10 deletions
diff --git a/lib/ext_server_name.c b/lib/ext_server_name.c
index 4e765153bb..bfcee9d367 100644
--- a/lib/ext_server_name.c
+++ b/lib/ext_server_name.c
@@ -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++)
diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c
index e930c1de3f..f071710034 100644
--- a/lib/gnutls_cipher.c
+++ b/lib/gnutls_cipher.c
@@ -453,6 +453,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)
*/
@@ -504,9 +512,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
@@ -515,6 +521,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)
diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c
index 2737edff85..cec3283221 100644
--- a/lib/gnutls_handshake.c
+++ b/lib/gnutls_handshake.c
@@ -1001,6 +1001,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;
}