1 |
vip-ire |
1.1 |
From dcea4ec698dcae39b7bba6f6aa08933cbfee6755 Mon Sep 17 00:00:00 2001 |
2 |
|
|
From: Stanislav Malyshev <stas@php.net> |
3 |
|
|
Date: Tue, 13 Aug 2013 22:20:33 -0700 |
4 |
|
|
Subject: [PATCH] Fix CVE-2013-4073 - handling of certs with null bytes |
5 |
|
|
|
6 |
|
|
--- |
7 |
|
|
NEWS | 4 ++ |
8 |
|
|
ext/openssl/openssl.c | 86 ++++++++++++++++++++++++++++++++++++- |
9 |
|
|
ext/openssl/tests/cve2013_4073.pem | 28 ++++++++++++ |
10 |
|
|
ext/openssl/tests/cve2013_4073.phpt | 19 ++++++++ |
11 |
|
|
4 files changed, 135 insertions(+), 2 deletions(-) |
12 |
|
|
create mode 100644 ext/openssl/tests/cve2013_4073.pem |
13 |
|
|
create mode 100644 ext/openssl/tests/cve2013_4073.phpt |
14 |
|
|
|
15 |
|
|
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c |
16 |
|
|
index 15696be..c7a9f5c 100644 |
17 |
|
|
--- a/ext/openssl/openssl.c |
18 |
|
|
+++ b/ext/openssl/openssl.c |
19 |
|
|
@@ -1326,6 +1326,74 @@ PHP_FUNCTION(openssl_x509_check_private_key) |
20 |
|
|
} |
21 |
|
|
/* }}} */ |
22 |
|
|
|
23 |
|
|
+/* Special handling of subjectAltName, see CVE-2013-4073 |
24 |
|
|
+ * Christian Heimes |
25 |
|
|
+ */ |
26 |
|
|
+ |
27 |
|
|
+static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) |
28 |
|
|
+{ |
29 |
|
|
+ GENERAL_NAMES *names; |
30 |
|
|
+ const X509V3_EXT_METHOD *method = NULL; |
31 |
|
|
+ long i, length, num; |
32 |
|
|
+ const unsigned char *p; |
33 |
|
|
+ |
34 |
|
|
+ method = X509V3_EXT_get(extension); |
35 |
|
|
+ if (method == NULL) { |
36 |
|
|
+ return -1; |
37 |
|
|
+ } |
38 |
|
|
+ |
39 |
|
|
+ p = extension->value->data; |
40 |
|
|
+ length = extension->value->length; |
41 |
|
|
+ if (method->it) { |
42 |
|
|
+ names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length, |
43 |
|
|
+ ASN1_ITEM_ptr(method->it))); |
44 |
|
|
+ } else { |
45 |
|
|
+ names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length)); |
46 |
|
|
+ } |
47 |
|
|
+ if (names == NULL) { |
48 |
|
|
+ return -1; |
49 |
|
|
+ } |
50 |
|
|
+ |
51 |
|
|
+ num = sk_GENERAL_NAME_num(names); |
52 |
|
|
+ for (i = 0; i < num; i++) { |
53 |
|
|
+ GENERAL_NAME *name; |
54 |
|
|
+ ASN1_STRING *as; |
55 |
|
|
+ name = sk_GENERAL_NAME_value(names, i); |
56 |
|
|
+ switch (name->type) { |
57 |
|
|
+ case GEN_EMAIL: |
58 |
|
|
+ BIO_puts(bio, "email:"); |
59 |
|
|
+ as = name->d.rfc822Name; |
60 |
|
|
+ BIO_write(bio, ASN1_STRING_data(as), |
61 |
|
|
+ ASN1_STRING_length(as)); |
62 |
|
|
+ break; |
63 |
|
|
+ case GEN_DNS: |
64 |
|
|
+ BIO_puts(bio, "DNS:"); |
65 |
|
|
+ as = name->d.dNSName; |
66 |
|
|
+ BIO_write(bio, ASN1_STRING_data(as), |
67 |
|
|
+ ASN1_STRING_length(as)); |
68 |
|
|
+ break; |
69 |
|
|
+ case GEN_URI: |
70 |
|
|
+ BIO_puts(bio, "URI:"); |
71 |
|
|
+ as = name->d.uniformResourceIdentifier; |
72 |
|
|
+ BIO_write(bio, ASN1_STRING_data(as), |
73 |
|
|
+ ASN1_STRING_length(as)); |
74 |
|
|
+ break; |
75 |
|
|
+ default: |
76 |
|
|
+ /* use builtin print for GEN_OTHERNAME, GEN_X400, |
77 |
|
|
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID |
78 |
|
|
+ */ |
79 |
|
|
+ GENERAL_NAME_print(bio, name); |
80 |
|
|
+ } |
81 |
|
|
+ /* trailing ', ' except for last element */ |
82 |
|
|
+ if (i < (num - 1)) { |
83 |
|
|
+ BIO_puts(bio, ", "); |
84 |
|
|
+ } |
85 |
|
|
+ } |
86 |
|
|
+ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); |
87 |
|
|
+ |
88 |
|
|
+ return 0; |
89 |
|
|
+} |
90 |
|
|
+ |
91 |
|
|
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true]) |
92 |
|
|
Returns an array of the fields/values of the CERT */ |
93 |
|
|
PHP_FUNCTION(openssl_x509_parse) |
94 |
|
|
@@ -1422,15 +1490,29 @@ PHP_FUNCTION(openssl_x509_parse) |
95 |
|
|
|
96 |
|
|
|
97 |
|
|
for (i = 0; i < X509_get_ext_count(cert); i++) { |
98 |
|
|
+ int nid; |
99 |
|
|
extension = X509_get_ext(cert, i); |
100 |
|
|
- if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) { |
101 |
|
|
+ nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); |
102 |
|
|
+ if (nid != NID_undef) { |
103 |
|
|
extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension))); |
104 |
|
|
} else { |
105 |
|
|
OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1); |
106 |
|
|
extname = buf; |
107 |
|
|
} |
108 |
|
|
bio_out = BIO_new(BIO_s_mem()); |
109 |
|
|
- if (X509V3_EXT_print(bio_out, extension, 0, 0)) { |
110 |
|
|
+ if (nid == NID_subject_alt_name) { |
111 |
|
|
+ if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) { |
112 |
|
|
+ add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); |
113 |
|
|
+ } else { |
114 |
|
|
+ zval_dtor(return_value); |
115 |
|
|
+ if (certresource == -1 && cert) { |
116 |
|
|
+ X509_free(cert); |
117 |
|
|
+ } |
118 |
|
|
+ BIO_free(bio_out); |
119 |
|
|
+ RETURN_FALSE; |
120 |
|
|
+ } |
121 |
|
|
+ } |
122 |
|
|
+ else if (X509V3_EXT_print(bio_out, extension, 0, 0)) { |
123 |
|
|
BIO_get_mem_ptr(bio_out, &bio_buf); |
124 |
|
|
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); |
125 |
|
|
} else { |
126 |
|
|
diff --git a/ext/openssl/tests/cve2013_4073.pem b/ext/openssl/tests/cve2013_4073.pem |
127 |
|
|
new file mode 100644 |
128 |
|
|
index 0000000..7ebb994 |
129 |
|
|
--- /dev/null |
130 |
|
|
+++ b/ext/openssl/tests/cve2013_4073.pem |
131 |
|
|
@@ -0,0 +1,28 @@ |
132 |
|
|
+-----BEGIN CERTIFICATE----- |
133 |
|
|
+MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx |
134 |
|
|
+DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ |
135 |
|
|
+eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg |
136 |
|
|
+RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y |
137 |
|
|
+ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw |
138 |
|
|
+NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI |
139 |
|
|
+DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv |
140 |
|
|
+ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt |
141 |
|
|
+ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq |
142 |
|
|
+hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB |
143 |
|
|
+BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j |
144 |
|
|
+pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P |
145 |
|
|
+vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv |
146 |
|
|
+KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA |
147 |
|
|
+oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL |
148 |
|
|
+08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV |
149 |
|
|
+HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E |
150 |
|
|
+BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu |
151 |
|
|
+Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251 |
152 |
|
|
+bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA |
153 |
|
|
+AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9 |
154 |
|
|
+i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j |
155 |
|
|
+HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk |
156 |
|
|
+kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx |
157 |
|
|
+VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW |
158 |
|
|
+RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ= |
159 |
|
|
+-----END CERTIFICATE----- |
160 |
|
|
diff --git a/ext/openssl/tests/cve2013_4073.phpt b/ext/openssl/tests/cve2013_4073.phpt |
161 |
|
|
new file mode 100644 |
162 |
|
|
index 0000000..e676ddf |
163 |
|
|
--- /dev/null |
164 |
|
|
+++ b/ext/openssl/tests/cve2013_4073.phpt |
165 |
|
|
@@ -0,0 +1,19 @@ |
166 |
|
|
+--TEST-- |
167 |
|
|
+CVE 2013-4073: Null-byte certificate handling |
168 |
|
|
+--SKIPIF-- |
169 |
|
|
+<?php |
170 |
|
|
+if (!extension_loaded("openssl")) die("skip"); |
171 |
|
|
+--FILE-- |
172 |
|
|
+<?php |
173 |
|
|
+$cert = file_get_contents(__DIR__ . '/cve2013_4073.pem'); |
174 |
|
|
+$info = openssl_x509_parse($cert); |
175 |
|
|
+var_export($info['extensions']); |
176 |
|
|
+ |
177 |
|
|
+--EXPECTF-- |
178 |
|
|
+array ( |
179 |
|
|
+ 'basicConstraints' => 'CA:FALSE', |
180 |
|
|
+ 'subjectKeyIdentifier' => '88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C', |
181 |
|
|
+ 'keyUsage' => 'Digital Signature, Non Repudiation, Key Encipherment', |
182 |
|
|
+ 'subjectAltName' => 'DNS:altnull.python.org' . "\0" . 'example.com, email:null@python.org' . "\0" . 'user@example.org, URI:http://null.python.org' . "\0" . 'http://example.org, IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1 |
183 |
|
|
+', |
184 |
|
|
+) |
185 |
|
|
-- |
186 |
|
|
1.7.11.5 |
187 |
|
|
|
188 |
|
|
From c1c49d6e3983c9ce0b43ffe7bf6e03b809ed048b Mon Sep 17 00:00:00 2001 |
189 |
|
|
From: Stanislav Malyshev <stas@php.net> |
190 |
|
|
Date: Mon, 19 Aug 2013 01:02:12 -0700 |
191 |
|
|
Subject: [PATCH] fix using wrong buffer pointer |
192 |
|
|
|
193 |
|
|
--- |
194 |
|
|
ext/openssl/openssl.c | 1 + |
195 |
|
|
1 file changed, 1 insertion(+) |
196 |
|
|
|
197 |
|
|
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c |
198 |
|
|
index c7a9f5c..e7672e4 100644 |
199 |
|
|
--- a/ext/openssl/openssl.c |
200 |
|
|
+++ b/ext/openssl/openssl.c |
201 |
|
|
@@ -1502,6 +1502,7 @@ PHP_FUNCTION(openssl_x509_parse) |
202 |
|
|
bio_out = BIO_new(BIO_s_mem()); |
203 |
|
|
if (nid == NID_subject_alt_name) { |
204 |
|
|
if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) { |
205 |
|
|
+ BIO_get_mem_ptr(bio_out, &bio_buf); |
206 |
|
|
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); |
207 |
|
|
} else { |
208 |
|
|
zval_dtor(return_value); |
209 |
|
|
-- |
210 |
|
|
1.7.11.5 |
211 |
|
|
|