1 |
vapier 10/11/26 22:51:08 |
2 |
|
3 |
Added: wget-1.12-sae.patch |
4 |
Log: |
5 |
Add patch from upstream for SSL SAE #344939 by Michał Górny. |
6 |
|
7 |
(Portage version: 2.2.0_alpha5/cvs/Linux x86_64) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 net-misc/wget/files/wget-1.12-sae.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-misc/wget/files/wget-1.12-sae.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/net-misc/wget/files/wget-1.12-sae.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: wget-1.12-sae.patch |
16 |
=================================================================== |
17 |
http://bugs.gentoo.org/344939 |
18 |
|
19 |
upstream commit 2317 |
20 |
|
21 |
2009-10-24 Petr Pisar <petr.pisar@×××××.cz> |
22 |
|
23 |
* openssl.c: Implement support for (multiple) subjectAltNames in |
24 |
X509 certificates, not just the commonName. |
25 |
|
26 |
--- src/openssl.c 2009-09-22 16:16:43 +0000 |
27 |
+++ src/openssl.c 2009-10-24 23:06:44 +0000 |
28 |
@@ -39,7 +39,7 @@ |
29 |
#include <string.h> |
30 |
|
31 |
#include <openssl/ssl.h> |
32 |
-#include <openssl/x509.h> |
33 |
+#include <openssl/x509v3.h> |
34 |
#include <openssl/err.h> |
35 |
#include <openssl/rand.h> |
36 |
|
37 |
@@ -486,9 +486,11 @@ |
38 |
ssl_check_certificate (int fd, const char *host) |
39 |
{ |
40 |
X509 *cert; |
41 |
+ GENERAL_NAMES *subjectAltNames; |
42 |
char common_name[256]; |
43 |
long vresult; |
44 |
bool success = true; |
45 |
+ bool alt_name_checked = false; |
46 |
|
47 |
/* If the user has specified --no-check-cert, we still want to warn |
48 |
him about problems with the server's certificate. */ |
49 |
@@ -536,7 +538,8 @@ |
50 |
break; |
51 |
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: |
52 |
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: |
53 |
- logprintf (LOG_NOTQUIET, _(" Self-signed certificate encountered.\n")); |
54 |
+ logprintf (LOG_NOTQUIET, |
55 |
+ _(" Self-signed certificate encountered.\n")); |
56 |
break; |
57 |
case X509_V_ERR_CERT_NOT_YET_VALID: |
58 |
logprintf (LOG_NOTQUIET, _(" Issued certificate not yet valid.\n")); |
59 |
@@ -558,10 +561,6 @@ |
60 |
/* Check that HOST matches the common name in the certificate. |
61 |
#### The following remains to be done: |
62 |
|
63 |
- - It should use dNSName/ipAddress subjectAltName extensions if |
64 |
- available; according to rfc2818: "If a subjectAltName extension |
65 |
- of type dNSName is present, that MUST be used as the identity." |
66 |
- |
67 |
- When matching against common names, it should loop over all |
68 |
common names and choose the most specific one, i.e. the last |
69 |
one, not the first one, which the current code picks. |
70 |
@@ -569,50 +568,123 @@ |
71 |
- Ensure that ASN1 strings from the certificate are encoded as |
72 |
UTF-8 which can be meaningfully compared to HOST. */ |
73 |
|
74 |
- X509_NAME *xname = X509_get_subject_name(cert); |
75 |
- common_name[0] = '\0'; |
76 |
- X509_NAME_get_text_by_NID (xname, NID_commonName, common_name, |
77 |
- sizeof (common_name)); |
78 |
+ subjectAltNames = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL); |
79 |
|
80 |
- if (!pattern_match (common_name, host)) |
81 |
+ if (subjectAltNames) |
82 |
{ |
83 |
- logprintf (LOG_NOTQUIET, _("\ |
84 |
-%s: certificate common name %s doesn't match requested host name %s.\n"), |
85 |
- severity, quote_n (0, common_name), quote_n (1, host)); |
86 |
- success = false; |
87 |
+ /* Test subject alternative names */ |
88 |
+ |
89 |
+ /* Do we want to check for dNSNAmes or ipAddresses (see RFC 2818)? |
90 |
+ * Signal it by host_in_octet_string. */ |
91 |
+ ASN1_OCTET_STRING *host_in_octet_string = NULL; |
92 |
+ host_in_octet_string = a2i_IPADDRESS (host); |
93 |
+ |
94 |
+ int numaltnames = sk_GENERAL_NAME_num (subjectAltNames); |
95 |
+ int i; |
96 |
+ for (i=0; i < numaltnames; i++) |
97 |
+ { |
98 |
+ const GENERAL_NAME *name = |
99 |
+ sk_GENERAL_NAME_value (subjectAltNames, i); |
100 |
+ if (name) |
101 |
+ { |
102 |
+ if (host_in_octet_string) |
103 |
+ { |
104 |
+ if (name->type == GEN_IPADD) |
105 |
+ { |
106 |
+ /* Check for ipAddress */ |
107 |
+ /* TODO: Should we convert between IPv4-mapped IPv6 |
108 |
+ * addresses and IPv4 addresses? */ |
109 |
+ alt_name_checked = true; |
110 |
+ if (!ASN1_STRING_cmp (host_in_octet_string, |
111 |
+ name->d.iPAddress)) |
112 |
+ break; |
113 |
+ } |
114 |
+ } |
115 |
+ else if (name->type == GEN_DNS) |
116 |
+ { |
117 |
+ /* Check for dNSName */ |
118 |
+ alt_name_checked = true; |
119 |
+ /* dNSName should be IA5String (i.e. ASCII), however who |
120 |
+ * does trust CA? Convert it into UTF-8 for sure. */ |
121 |
+ unsigned char *name_in_utf8 = NULL; |
122 |
+ if (0 <= ASN1_STRING_to_UTF8 (&name_in_utf8, name->d.dNSName)) |
123 |
+ { |
124 |
+ /* Compare and check for NULL attack in ASN1_STRING */ |
125 |
+ if (pattern_match ((char *)name_in_utf8, host) && |
126 |
+ (strlen ((char *)name_in_utf8) == |
127 |
+ ASN1_STRING_length (name->d.dNSName))) |
128 |
+ { |
129 |
+ OPENSSL_free (name_in_utf8); |
130 |
+ break; |
131 |
+ } |
132 |
+ OPENSSL_free (name_in_utf8); |
133 |
+ } |
134 |
+ } |
135 |
+ } |
136 |
+ } |
137 |
+ sk_GENERAL_NAME_free (subjectAltNames); |
138 |
+ if (host_in_octet_string) |
139 |
+ ASN1_OCTET_STRING_free(host_in_octet_string); |
140 |
+ |
141 |
+ if (alt_name_checked == true && i >= numaltnames) |
142 |
+ { |
143 |
+ logprintf (LOG_NOTQUIET, |
144 |
+ _("%s: no certificate subject alternative name matches\n" |
145 |
+ "\trequested host name %s.\n"), |
146 |
+ severity, quote_n (1, host)); |
147 |
+ success = false; |
148 |
+ } |
149 |
} |
150 |
- else |
151 |
+ |
152 |
+ if (alt_name_checked == false) |
153 |
{ |
154 |
- /* We now determine the length of the ASN1 string. If it differs from |
155 |
- * common_name's length, then there is a \0 before the string terminates. |
156 |
- * This can be an instance of a null-prefix attack. |
157 |
- * |
158 |
- * https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike |
159 |
- * */ |
160 |
- |
161 |
- int i = -1, j; |
162 |
- X509_NAME_ENTRY *xentry; |
163 |
- ASN1_STRING *sdata; |
164 |
- |
165 |
- if (xname) { |
166 |
- for (;;) |
167 |
- { |
168 |
- j = X509_NAME_get_index_by_NID (xname, NID_commonName, i); |
169 |
- if (j == -1) break; |
170 |
- i = j; |
171 |
+ /* Test commomName */ |
172 |
+ X509_NAME *xname = X509_get_subject_name(cert); |
173 |
+ common_name[0] = '\0'; |
174 |
+ X509_NAME_get_text_by_NID (xname, NID_commonName, common_name, |
175 |
+ sizeof (common_name)); |
176 |
+ |
177 |
+ if (!pattern_match (common_name, host)) |
178 |
+ { |
179 |
+ logprintf (LOG_NOTQUIET, _("\ |
180 |
+ %s: certificate common name %s doesn't match requested host name %s.\n"), |
181 |
+ severity, quote_n (0, common_name), quote_n (1, host)); |
182 |
+ success = false; |
183 |
+ } |
184 |
+ else |
185 |
+ { |
186 |
+ /* We now determine the length of the ASN1 string. If it |
187 |
+ * differs from common_name's length, then there is a \0 |
188 |
+ * before the string terminates. This can be an instance of a |
189 |
+ * null-prefix attack. |
190 |
+ * |
191 |
+ * https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike |
192 |
+ * */ |
193 |
+ |
194 |
+ int i = -1, j; |
195 |
+ X509_NAME_ENTRY *xentry; |
196 |
+ ASN1_STRING *sdata; |
197 |
+ |
198 |
+ if (xname) { |
199 |
+ for (;;) |
200 |
+ { |
201 |
+ j = X509_NAME_get_index_by_NID (xname, NID_commonName, i); |
202 |
+ if (j == -1) break; |
203 |
+ i = j; |
204 |
+ } |
205 |
} |
206 |
- } |
207 |
|
208 |
- xentry = X509_NAME_get_entry(xname,i); |
209 |
- sdata = X509_NAME_ENTRY_get_data(xentry); |
210 |
- if (strlen (common_name) != ASN1_STRING_length (sdata)) |
211 |
- { |
212 |
- logprintf (LOG_NOTQUIET, _("\ |
213 |
-%s: certificate common name is invalid (contains a NUL character).\n\ |
214 |
-This may be an indication that the host is not who it claims to be\n\ |
215 |
-(that is, it is not the real %s).\n"), |
216 |
- severity, quote (host)); |
217 |
- success = false; |
218 |
+ xentry = X509_NAME_get_entry(xname,i); |
219 |
+ sdata = X509_NAME_ENTRY_get_data(xentry); |
220 |
+ if (strlen (common_name) != ASN1_STRING_length (sdata)) |
221 |
+ { |
222 |
+ logprintf (LOG_NOTQUIET, _("\ |
223 |
+ %s: certificate common name is invalid (contains a NUL character).\n\ |
224 |
+ This may be an indication that the host is not who it claims to be\n\ |
225 |
+ (that is, it is not the real %s).\n"), |
226 |
+ severity, quote (host)); |
227 |
+ success = false; |
228 |
+ } |
229 |
} |
230 |
} |
231 |
|
232 |
@@ -631,3 +703,7 @@ |
233 |
/* Allow --no-check-cert to disable certificate checking. */ |
234 |
return opt.check_cert ? success : true; |
235 |
} |
236 |
+ |
237 |
+/* |
238 |
+ * vim: tabstop=2 shiftwidth=2 softtabstop=2 |
239 |
+ */ |