Package: gnutls11
Version: unavailable; reported 2005-05-04
Severity: important
Tags: security patch

http://lists.gnupg.org/pipermail/gnutls-dev/2005-April/000858.html mentions
a DoS vulnerability in gnutls' record packet parsing. It's fixed in 1.0.25,
which is obviously not an option. Unfortunately they are unwilling to provide
further details:

> We do not have the resources to analyze and write an explanation of
> this security problem.  Volunteers who want to read the bug reports
> and the CVS changes, and write up an explanation in plain English, are
> most welcome!  Having a detailed track record of security problems can
> be a useful reference when discussing security in free software
> packages in general.  Naturally, if you wish to sponsor us to do this
> work for you, please contact me.

I've had a look at the GNUTLS CVS and the changelog points to two combined
fixes that have been backported from 1.2: 
2005-04-27  nmav <[EMAIL PROTECTED]>

* NEWS, lib/gnutls_cipher.c, lib/gnutls_mpi.h, lib/x509/privkey.c:
  Backported from the new stable branch:
  - Corrected bug in record packet parsing that could lead
    to a denial of service attack.
  - Corrected bug in RSA key export.
                                          
I've attached two patches; the above change against 1.0.16 and the portion
of the patch that is only related to the DoS. Please check whether the
RSA part is needed for Sarge as well.

Cheers,
         Moritz
-- 
Moritz Muehlenhoff [EMAIL PROTECTED]     fon: +49 421 22 232- 0
Development        Linux for Your Business       fax: +49 421 22 232-99
Univention GmbH    http://www.univention.de/   mobil: +49 175 22 999 23

-- System Information:
Debian Release: 3.0
Architecture: i386
Kernel: Linux anton 2.4.29-univention.1 #1 SMP Thu Jan 27 17:08:46 CET 2005 i686
Locale: [EMAIL PROTECTED], [EMAIL PROTECTED]

diff -Naur gnutls11-1.0.16.orig/lib/gnutls_cipher.c gnutls11-1.0.16/lib/gnutls_cipher.c
--- gnutls11-1.0.16.orig/lib/gnutls_cipher.c	Fri Feb 27 17:51:58 2004
+++ gnutls11-1.0.16/lib/gnutls_cipher.c	Wed May  4 13:42:48 2005
@@ -448,7 +448,7 @@
 		
 		/* Check the pading bytes (TLS 1.x)
 		 */
-		if ( ver >= GNUTLS_TLS1)
+		if ( ver >= GNUTLS_TLS1 && pad_failed==0)
 		for (i=2;i<pad;i++) {
 			if (ciphertext.data[ciphertext.size-i] != ciphertext.data[ciphertext.size - 1]) 
 				pad_failed = GNUTLS_E_DECRYPTION_FAILED;
diff -Naur gnutls11-1.0.16.orig/lib/gnutls_mpi.h gnutls11-1.0.16/lib/gnutls_mpi.h
--- gnutls11-1.0.16.orig/lib/gnutls_mpi.h	Sun Jun  6 16:24:50 2004
+++ gnutls11-1.0.16/lib/gnutls_mpi.h	Wed May  4 13:42:41 2005
@@ -26,6 +26,7 @@
 #define _gnutls_mpi_mul gcry_mpi_mul
 #define _gnutls_mpi_add gcry_mpi_add
 #define _gnutls_mpi_add_ui gcry_mpi_add_ui
+#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui
 #define _gnutls_mpi_mul_ui gcry_mpi_mul_ui
 #define _gnutls_prime_check gcry_prime_check
 #define _gnutls_mpi_div gcry_mpi_div
diff -Naur gnutls11-1.0.16.orig/lib/x509/privkey.c gnutls11-1.0.16/lib/x509/privkey.c
--- gnutls11-1.0.16.orig/lib/x509/privkey.c	Wed May  4 13:34:50 2005
+++ gnutls11-1.0.16/lib/x509/privkey.c	Wed May  4 13:42:37 2005
@@ -188,7 +188,6 @@
 		goto error;
 	}
 
-#if 1
 	/* Calculate the coefficient. This is because the gcrypt
 	 * library is uses the p,q in the reverse order.
 	 */
@@ -202,13 +201,7 @@
 
 	_gnutls_mpi_invm(pkey->params[5], pkey->params[3], pkey->params[4]);
 	/*				p, q */
-#else
-	if ( (result=_gnutls_x509_read_int( pkey_asn, "coefficient",
-		&pkey->params[5])) < 0) {
-		gnutls_assert();
-		goto error;
-	}
-#endif
+
 	pkey->params_size = 6;
 
 	return pkey_asn;
@@ -471,13 +464,17 @@
 		return GNUTLS_E_MPI_SCAN_FAILED;
 	}
 
-	siz = u->size;
-	if (_gnutls_mpi_scan(&key->params[5], u->data, &siz)) {
+	key->params[5] =
+		_gnutls_mpi_snew(_gnutls_mpi_get_nbits(key->params[0]));
+
+	if (key->params[5] == NULL) {
 		gnutls_assert();
 		FREE_RSA_PRIVATE_PARAMS;
-		return GNUTLS_E_MPI_SCAN_FAILED;
+		return GNUTLS_E_MEMORY_ERROR;
 	}
 
+	_gnutls_mpi_invm(key->params[5], key->params[3], key->params[4]);
+
 	ret = _encode_rsa( &key->key, key->params);
 	if (ret < 0) {
 		gnutls_assert();
@@ -652,6 +649,8 @@
 	gnutls_datum* u)
 {
 	size_t siz;
+	int result;
+	GNUTLS_MPI coeff;
 
 	if (key == NULL) {
 		gnutls_assert();
@@ -728,22 +727,34 @@
 	_gnutls_mpi_print(q->data, &siz, key->params[4]);
 
 	/* U */
-	siz = 0;
-	_gnutls_mpi_print(NULL, &siz, key->params[5]);
+	coeff =
+		_gnutls_mpi_snew(_gnutls_mpi_get_nbits(key->params[0]));
 
-	u->data = gnutls_malloc(siz);
-	if (u->data == NULL) {
+	if (coeff == NULL) {
+		gnutls_assert();
 		_gnutls_free_datum( m);
+		_gnutls_free_datum( q);
 		_gnutls_free_datum( e);
 		_gnutls_free_datum( d);
 		_gnutls_free_datum( p);
-		_gnutls_free_datum( q);
 		return GNUTLS_E_MEMORY_ERROR;
 	}
 
-	u->size = siz;
-	_gnutls_mpi_print(u->data, &siz, key->params[5]);
-	
+	_gnutls_mpi_invm(coeff, key->params[4], key->params[3]);
+
+	result = _gnutls_mpi_dprint(u, coeff);
+	_gnutls_mpi_release( &coeff);
+
+	if (result < 0) {
+		gnutls_assert();
+		_gnutls_free_datum( m);
+		_gnutls_free_datum( q);
+		_gnutls_free_datum( e);
+		_gnutls_free_datum( d);
+		_gnutls_free_datum( p);
+		return result;
+	}
+
 	return 0;
 
 }
@@ -857,12 +868,12 @@
 	opaque * m_data, *pube_data, *prie_data;
 	opaque* p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
 	opaque * all_data = NULL, *p;
-	GNUTLS_MPI exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL;
+	GNUTLS_MPI exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u=NULL;
 	opaque null = '\0';
 
 	/* Read all the sizes */
 	total = 0;
-	for (i=0;i<6;i++) {
+	for (i=0;i<5;i++) {
 		_gnutls_mpi_print_lz( NULL, &size[i], params[i]);
 		total += size[i];
 	}
@@ -896,9 +907,21 @@
 		result = GNUTLS_E_MEMORY_ERROR;
 		goto cleanup;
 	}
+
+	/* U */
+	u = _gnutls_mpi_salloc_like(params[3]);
+	if (u == NULL) {
+		gnutls_assert();
+		result = GNUTLS_E_MEMORY_ERROR;
+		goto cleanup;
+	}
+	_gnutls_mpi_invm(u, params[4], params[3]);
+	/* inverse of q mod p */
+	_gnutls_mpi_print_lz(NULL, &size[5], u);
+	total += size[5];
 	
-	_gnutls_mpi_add_ui( p1, params[3], -1);
-	_gnutls_mpi_add_ui( q1, params[4], -1);
+	_gnutls_mpi_sub_ui( p1, params[3], 1);
+	_gnutls_mpi_sub_ui( q1, params[4], 1);
 
 	_gnutls_mpi_mod( exp1, params[2], p1);
 	_gnutls_mpi_mod( exp2, params[2], q1);

<<attachment: /home/jmm/sc/tls/gnutls-CAN-2005-1431-DoS.patch>>

Reply via email to