File CVE-2009-2730.patch of Package gnutls
Index: gnutls-2.4.1/lib/x509/common.c
===================================================================
--- gnutls-2.4.1.orig/lib/x509/common.c
+++ gnutls-2.4.1/lib/x509/common.c
@@ -181,7 +181,7 @@ _gnutls_x509_oid_data2string (const char
{
char str[MAX_STRING_LEN], tmpname[128];
const char *ANAME = NULL;
- int CHOICE = -1, len = -1, result;
+ int CHOICE = -1, len = -1, result, i;
ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
char asn1_err[MAX_ERROR_DESCRIPTION_SIZE] = "";
@@ -312,6 +312,12 @@ _gnutls_x509_oid_data2string (const char
}
+ /* Convert null char in the name to '?'
+ * to protect applications */
+ for (i=0;i<*res_size;i++) {
+ if (res[i] == 0) res[i]='?';
+ }
+
return 0;
}
Index: gnutls-2.4.1/lib/gnutls_str.c
===================================================================
--- gnutls-2.4.1.orig/lib/gnutls_str.c
+++ gnutls-2.4.1/lib/gnutls_str.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation
+ * Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009 Free Software Foundation
*
* Author: Nikos Mavrogiannopoulos
*
@@ -331,16 +331,21 @@ _gnutls_hex2bin (const opaque * hex_data
/* compare hostname against certificate, taking account of wildcards
* return 1 on success or 0 on error
+ *
+ * note: certnamesize is required as X509 certs can contain embedded NULs in
+ * the strings such as CN or subjectAltName
*/
int
-_gnutls_hostname_compare (const char *certname, const char *hostname)
+_gnutls_hostname_compare (const char *certname,
+ size_t certnamesize,
+ const char *hostname)
{
/* find the first different character */
- for (; *certname && *hostname && toupper(*certname) == toupper(*hostname); certname++, hostname++)
+ for (; *certname && *hostname && toupper(*certname) == toupper(*hostname); certname++, hostname++, certnamesize--)
;
/* the strings are the same */
- if (strlen (certname) == 0 && strlen (hostname) == 0)
+ if (certnamesize == 0 && *hostname == '\0')
return 1;
if (*certname == '*')
@@ -348,15 +353,16 @@ _gnutls_hostname_compare (const char *ce
/* a wildcard certificate */
certname++;
-
+ certnamesize--;
+
while (1)
{
- /* Use a recursive call to allow multiple wildcards */
- if (_gnutls_hostname_compare (certname, hostname))
- {
- return 1;
- }
- /* wildcards are only allowed to match a single domain component or component fragment */
+ /* Use a recursive call to allow multiple wildcards */
+ if (_gnutls_hostname_compare (certname, certnamesize, hostname))
+ return 1;
+
+ /* wildcards are only allowed to match a single domain
+ component or component fragment */
if (*hostname == '\0' || *hostname == '.')
break;
hostname++;
Index: gnutls-2.4.1/lib/gnutls_str.h
===================================================================
--- gnutls-2.4.1.orig/lib/gnutls_str.h
+++ gnutls-2.4.1/lib/gnutls_str.h
@@ -62,7 +62,7 @@ char *_gnutls_bin2hex (const void *old,
int _gnutls_hex2bin (const opaque * hex_data, int hex_size, opaque * bin_data,
size_t * bin_size);
-int _gnutls_hostname_compare (const char *certname, const char *hostname);
+int _gnutls_hostname_compare (const char *certname, size_t certnamesize, const char *hostname);
#define MAX_CN 256
#endif
Index: gnutls-2.4.1/lib/openpgp/pgp.c
===================================================================
--- gnutls-2.4.1.orig/lib/openpgp/pgp.c
+++ gnutls-2.4.1/lib/openpgp/pgp.c
@@ -566,7 +566,7 @@ gnutls_openpgp_crt_check_hostname (gnutl
if (ret == 0)
{
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
return 1;
}
}
Index: gnutls-2.4.1/lib/x509/common.c
===================================================================
--- gnutls-2.4.1.orig/lib/x509/common.c
+++ gnutls-2.4.1/lib/x509/common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
*
* Author: Nikos Mavrogiannopoulos
*
@@ -241,6 +241,10 @@ _gnutls_x509_oid_data2string (const char
{
str[len] = 0;
+ /* Refuse to deal with strings containing NULs. */
+ if (strlen (str) != len)
+ return GNUTLS_E_ASN1_DER_ERROR;
+
if (res)
_gnutls_str_cpy (res, *res_size, str);
*res_size = len;
@@ -291,25 +295,27 @@ _gnutls_x509_oid_data2string (const char
non_printable = 0;
}
- if (res)
+ if (non_printable == 0)
{
- if (non_printable == 0)
- {
- str[len] = 0;
- _gnutls_str_cpy (res, *res_size, str);
- *res_size = len;
- }
- else
+ str[len] = 0;
+
+ /* Refuse to deal with strings containing NULs. */
+ if (strlen (str) != len)
+ return GNUTLS_E_ASN1_DER_ERROR;
+
+ if (res)
+ _gnutls_str_cpy (res, *res_size, str);
+ *res_size = len;
+ }
+ else
+ {
+ result = _gnutls_x509_data2hex (str, len, res, res_size);
+ if (result < 0)
{
- result = _gnutls_x509_data2hex (str, len, res, res_size);
- if (result < 0)
- {
gnutls_assert ();
return result;
- }
}
}
-
}
/* Convert null char in the name to '?'
Index: gnutls-2.4.1/lib/x509/output.c
===================================================================
--- gnutls-2.4.1.orig/lib/x509/output.c
+++ gnutls-2.4.1/lib/x509/output.c
@@ -272,6 +272,17 @@ print_crldist (gnutls_string * str, gnut
return;
}
+ if ((err == GNUTLS_SAN_DNSNAME
+ || err == GNUTLS_SAN_RFC822NAME
+ || err == GNUTLS_SAN_URI) &&
+ strlen (buffer) != size)
+ {
+ adds (str, _("warning: distributionPoint contains an embedded NUL, "
+ "replacing with '!'\n"));
+ while (strlen (buffer) < size)
+ buffer[strlen (buffer)] = '!';
+ }
+
switch (err)
{
case GNUTLS_SAN_DNSNAME:
@@ -423,6 +434,18 @@ print_san (gnutls_string * str, gnutls_x
return;
}
+ if ((err == GNUTLS_SAN_DNSNAME
+ || err == GNUTLS_SAN_RFC822NAME
+ || err == GNUTLS_SAN_URI) &&
+ strlen (buffer) != size)
+ {
+ adds (str, _("warning: SAN contains an embedded NUL, "
+ "replacing with '!'\n"));
+ while (strlen (buffer) < size)
+ buffer[strlen (buffer)] = '!';
+ }
+
+
switch (err)
{
case GNUTLS_SAN_DNSNAME:
@@ -481,7 +504,17 @@ print_san (gnutls_string * str, gnutls_x
}
if (err == GNUTLS_SAN_OTHERNAME_XMPP)
- addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
+ {
+ if (strlen (buffer) != size)
+ {
+ adds (str, _("warning: SAN contains an embedded NUL, "
+ "replacing with '!'\n"));
+ while (strlen (buffer) < size)
+ buffer[strlen (buffer)] = '!';
+ }
+
+ addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
+ }
else
{
addf (str, _("\t\t\totherName OID: %.*s\n"), oidsize, oid);
Index: gnutls-2.4.1/lib/x509/rfc2818_hostname.c
===================================================================
--- gnutls-2.4.1.orig/lib/x509/rfc2818_hostname.c
+++ gnutls-2.4.1/lib/x509/rfc2818_hostname.c
@@ -74,7 +74,7 @@ gnutls_x509_crt_check_hostname (gnutls_x
if (ret == GNUTLS_SAN_DNSNAME)
{
found_dnsname = 1;
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
{
return 1;
}
@@ -84,7 +84,7 @@ gnutls_x509_crt_check_hostname (gnutls_x
found_dnsname = 1; /* RFC 2818 is unclear whether the CN
should be compared for IP addresses
too, but we won't do it. */
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
{
return 1;
}
@@ -104,7 +104,7 @@ gnutls_x509_crt_check_hostname (gnutls_x
return 0;
}
- if (_gnutls_hostname_compare (dnsname, hostname))
+ if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
{
return 1;
}
Index: gnutls-2.4.1/lib/x509/common.c
===================================================================
--- gnutls-2.4.1.orig/lib/x509/common.c
+++ gnutls-2.4.1/lib/x509/common.c
@@ -181,7 +181,7 @@ _gnutls_x509_oid_data2string (const char
{
char str[MAX_STRING_LEN], tmpname[128];
const char *ANAME = NULL;
- int CHOICE = -1, len = -1, result, i;
+ int CHOICE = -1, len = -1, result;
ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
char asn1_err[MAX_ERROR_DESCRIPTION_SIZE] = "";
@@ -318,12 +318,6 @@ _gnutls_x509_oid_data2string (const char
}
}
- /* Convert null char in the name to '?'
- * to protect applications */
- for (i=0;i<*res_size;i++) {
- if (res[i] == 0) res[i]='?';
- }
-
return 0;
}