[8.09] [packages] gnutls: fix 2 vulnerabilities allowing Man-in-the-Middle attacks
[openwrt/svn-archive/archive.git] / libs / gnutls / patches / 902-cve-2009-2730.patch
1 http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-2730
2
3 --- a/lib/gnutls_str.c
4 +++ b/lib/gnutls_str.c
5 @@ -1,5 +1,5 @@
6 /*
7 - * Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation
8 + * Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009 Free Software Foundation
9 *
10 * Author: Nikos Mavrogiannopoulos
11 *
12 @@ -331,16 +331,21 @@ _gnutls_hex2bin (const opaque * hex_data
13
14 /* compare hostname against certificate, taking account of wildcards
15 * return 1 on success or 0 on error
16 + *
17 + * note: certnamesize is required as X509 certs can contain embedded NULs in
18 + * the strings such as CN or subjectAltName
19 */
20 int
21 -_gnutls_hostname_compare (const char *certname, const char *hostname)
22 +_gnutls_hostname_compare (const char *certname,
23 + size_t certnamesize,
24 + const char *hostname)
25 {
26 /* find the first different character */
27 - for (; *certname && *hostname && toupper(*certname) == toupper(*hostname); certname++, hostname++)
28 + for (; *certname && *hostname && toupper(*certname) == toupper(*hostname); certname++, hostname++, certnamesize--)
29 ;
30
31 /* the strings are the same */
32 - if (strlen (certname) == 0 && strlen (hostname) == 0)
33 + if (certnamesize == 0 && *hostname == '\0')
34 return 1;
35
36 if (*certname == '*')
37 @@ -348,15 +353,16 @@ _gnutls_hostname_compare (const char *ce
38 /* a wildcard certificate */
39
40 certname++;
41 -
42 + certnamesize--;
43 +
44 while (1)
45 {
46 /* Use a recursive call to allow multiple wildcards */
47 - if (_gnutls_hostname_compare (certname, hostname))
48 - {
49 - return 1;
50 - }
51 - /* wildcards are only allowed to match a single domain component or component fragment */
52 + if (_gnutls_hostname_compare (certname, certnamesize, hostname))
53 + return 1;
54 +
55 + /* wildcards are only allowed to match a single domain
56 + component or component fragment */
57 if (*hostname == '\0' || *hostname == '.')
58 break;
59 hostname++;
60 --- a/lib/gnutls_str.h
61 +++ b/lib/gnutls_str.h
62 @@ -62,7 +62,7 @@ char *_gnutls_bin2hex (const void *old,
63 int _gnutls_hex2bin (const opaque * hex_data, int hex_size, opaque * bin_data,
64 size_t * bin_size);
65
66 -int _gnutls_hostname_compare (const char *certname, const char *hostname);
67 +int _gnutls_hostname_compare (const char *certname, size_t certnamesize, const char *hostname);
68 #define MAX_CN 256
69
70 #endif
71 --- a/lib/openpgp/pgp.c
72 +++ b/lib/openpgp/pgp.c
73 @@ -566,7 +566,7 @@ gnutls_openpgp_crt_check_hostname (gnutl
74
75 if (ret == 0)
76 {
77 - if (_gnutls_hostname_compare (dnsname, hostname))
78 + if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
79 return 1;
80 }
81 }
82 --- a/lib/x509/common.c
83 +++ b/lib/x509/common.c
84 @@ -1,5 +1,5 @@
85 /*
86 - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
87 + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
88 *
89 * Author: Nikos Mavrogiannopoulos
90 *
91 @@ -241,6 +241,10 @@ _gnutls_x509_oid_data2string (const char
92 {
93 str[len] = 0;
94
95 + /* Refuse to deal with strings containing NULs. */
96 + if (strlen (str) != len)
97 + return GNUTLS_E_ASN1_DER_ERROR;
98 +
99 if (res)
100 _gnutls_str_cpy (res, *res_size, str);
101 *res_size = len;
102 @@ -291,25 +295,27 @@ _gnutls_x509_oid_data2string (const char
103 non_printable = 0;
104 }
105
106 - if (res)
107 + if (non_printable == 0)
108 {
109 - if (non_printable == 0)
110 - {
111 - str[len] = 0;
112 - _gnutls_str_cpy (res, *res_size, str);
113 - *res_size = len;
114 - }
115 - else
116 + str[len] = 0;
117 +
118 + /* Refuse to deal with strings containing NULs. */
119 + if (strlen (str) != len)
120 + return GNUTLS_E_ASN1_DER_ERROR;
121 +
122 + if (res)
123 + _gnutls_str_cpy (res, *res_size, str);
124 + *res_size = len;
125 + }
126 + else
127 + {
128 + result = _gnutls_x509_data2hex (str, len, res, res_size);
129 + if (result < 0)
130 {
131 - result = _gnutls_x509_data2hex (str, len, res, res_size);
132 - if (result < 0)
133 - {
134 - gnutls_assert ();
135 - return result;
136 - }
137 + gnutls_assert ();
138 + return result;
139 }
140 }
141 -
142 }
143
144 return 0;
145 --- a/lib/x509/output.c
146 +++ b/lib/x509/output.c
147 @@ -272,6 +272,17 @@ print_crldist (gnutls_string * str, gnut
148 return;
149 }
150
151 + if ((err == GNUTLS_SAN_DNSNAME
152 + || err == GNUTLS_SAN_RFC822NAME
153 + || err == GNUTLS_SAN_URI) &&
154 + strlen (buffer) != size)
155 + {
156 + adds (str, _("warning: distributionPoint contains an embedded NUL, "
157 + "replacing with '!'\n"));
158 + while (strlen (buffer) < size)
159 + buffer[strlen (buffer)] = '!';
160 + }
161 +
162 switch (err)
163 {
164 case GNUTLS_SAN_DNSNAME:
165 @@ -423,6 +434,17 @@ print_san (gnutls_string * str, gnutls_x
166 return;
167 }
168
169 + if ((err == GNUTLS_SAN_DNSNAME
170 + || err == GNUTLS_SAN_RFC822NAME
171 + || err == GNUTLS_SAN_URI) &&
172 + strlen (buffer) != size)
173 + {
174 + adds (str, _("warning: SAN contains an embedded NUL, "
175 + "replacing with '!'\n"));
176 + while (strlen (buffer) < size)
177 + buffer[strlen (buffer)] = '!';
178 + }
179 +
180 switch (err)
181 {
182 case GNUTLS_SAN_DNSNAME:
183 @@ -481,7 +503,17 @@ print_san (gnutls_string * str, gnutls_x
184 }
185
186 if (err == GNUTLS_SAN_OTHERNAME_XMPP)
187 - addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
188 + {
189 + if (strlen (buffer) != size)
190 + {
191 + adds (str, _("warning: SAN contains an embedded NUL, "
192 + "replacing with '!'\n"));
193 + while (strlen (buffer) < size)
194 + buffer[strlen (buffer)] = '!';
195 + }
196 +
197 + addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
198 + }
199 else
200 {
201 addf (str, _("\t\t\totherName OID: %.*s\n"), oidsize, oid);
202 --- a/lib/x509/rfc2818_hostname.c
203 +++ b/lib/x509/rfc2818_hostname.c
204 @@ -74,7 +74,7 @@ gnutls_x509_crt_check_hostname (gnutls_x
205 if (ret == GNUTLS_SAN_DNSNAME)
206 {
207 found_dnsname = 1;
208 - if (_gnutls_hostname_compare (dnsname, hostname))
209 + if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
210 {
211 return 1;
212 }
213 @@ -84,7 +84,7 @@ gnutls_x509_crt_check_hostname (gnutls_x
214 found_dnsname = 1; /* RFC 2818 is unclear whether the CN
215 should be compared for IP addresses
216 too, but we won't do it. */
217 - if (_gnutls_hostname_compare (dnsname, hostname))
218 + if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
219 {
220 return 1;
221 }
222 @@ -104,7 +104,7 @@ gnutls_x509_crt_check_hostname (gnutls_x
223 return 0;
224 }
225
226 - if (_gnutls_hostname_compare (dnsname, hostname))
227 + if (_gnutls_hostname_compare (dnsname, dnsnamesize, hostname))
228 {
229 return 1;
230 }