Skip to content

Commit dcea4ec

Browse files
committed
Fix CVE-2013-4073 - handling of certs with null bytes
1 parent 7c9bb87 commit dcea4ec

File tree

4 files changed

+135
-2
lines changed

4 files changed

+135
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2013, PHP 5.3.28
44

5+
- Openssl:
6+
. Fixed handling null bytes in subjectAltName (CVE-2013-4073).
7+
(Christian Heimes)
8+
59
11 Jul 2013, PHP 5.3.27
610

711
- Core:

ext/openssl/openssl.c

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,74 @@ PHP_FUNCTION(openssl_x509_check_private_key)
13261326
}
13271327
/* }}} */
13281328

1329+
/* Special handling of subjectAltName, see CVE-2013-4073
1330+
* Christian Heimes
1331+
*/
1332+
1333+
static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
1334+
{
1335+
GENERAL_NAMES *names;
1336+
const X509V3_EXT_METHOD *method = NULL;
1337+
long i, length, num;
1338+
const unsigned char *p;
1339+
1340+
method = X509V3_EXT_get(extension);
1341+
if (method == NULL) {
1342+
return -1;
1343+
}
1344+
1345+
p = extension->value->data;
1346+
length = extension->value->length;
1347+
if (method->it) {
1348+
names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
1349+
ASN1_ITEM_ptr(method->it)));
1350+
} else {
1351+
names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
1352+
}
1353+
if (names == NULL) {
1354+
return -1;
1355+
}
1356+
1357+
num = sk_GENERAL_NAME_num(names);
1358+
for (i = 0; i < num; i++) {
1359+
GENERAL_NAME *name;
1360+
ASN1_STRING *as;
1361+
name = sk_GENERAL_NAME_value(names, i);
1362+
switch (name->type) {
1363+
case GEN_EMAIL:
1364+
BIO_puts(bio, "email:");
1365+
as = name->d.rfc822Name;
1366+
BIO_write(bio, ASN1_STRING_data(as),
1367+
ASN1_STRING_length(as));
1368+
break;
1369+
case GEN_DNS:
1370+
BIO_puts(bio, "DNS:");
1371+
as = name->d.dNSName;
1372+
BIO_write(bio, ASN1_STRING_data(as),
1373+
ASN1_STRING_length(as));
1374+
break;
1375+
case GEN_URI:
1376+
BIO_puts(bio, "URI:");
1377+
as = name->d.uniformResourceIdentifier;
1378+
BIO_write(bio, ASN1_STRING_data(as),
1379+
ASN1_STRING_length(as));
1380+
break;
1381+
default:
1382+
/* use builtin print for GEN_OTHERNAME, GEN_X400,
1383+
* GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
1384+
*/
1385+
GENERAL_NAME_print(bio, name);
1386+
}
1387+
/* trailing ', ' except for last element */
1388+
if (i < (num - 1)) {
1389+
BIO_puts(bio, ", ");
1390+
}
1391+
}
1392+
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1393+
1394+
return 0;
1395+
}
1396+
13291397
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])
13301398
Returns an array of the fields/values of the CERT */
13311399
PHP_FUNCTION(openssl_x509_parse)
@@ -1422,15 +1490,29 @@ PHP_FUNCTION(openssl_x509_parse)
14221490

14231491

14241492
for (i = 0; i < X509_get_ext_count(cert); i++) {
1493+
int nid;
14251494
extension = X509_get_ext(cert, i);
1426-
if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) {
1495+
nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
1496+
if (nid != NID_undef) {
14271497
extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension)));
14281498
} else {
14291499
OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1);
14301500
extname = buf;
14311501
}
14321502
bio_out = BIO_new(BIO_s_mem());
1433-
if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
1503+
if (nid == NID_subject_alt_name) {
1504+
if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
1505+
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
1506+
} else {
1507+
zval_dtor(return_value);
1508+
if (certresource == -1 && cert) {
1509+
X509_free(cert);
1510+
}
1511+
BIO_free(bio_out);
1512+
RETURN_FALSE;
1513+
}
1514+
}
1515+
else if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
14341516
BIO_get_mem_ptr(bio_out, &bio_buf);
14351517
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
14361518
} else {

ext/openssl/tests/cve2013_4073.pem

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
3+
DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
4+
eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
5+
RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
6+
ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
7+
NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
8+
DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
9+
ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
10+
ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
11+
hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
12+
BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
13+
pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
14+
vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
15+
KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
16+
oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
17+
08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
18+
HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
19+
BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
20+
Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
21+
bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
22+
AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
23+
i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
24+
HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
25+
kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
26+
VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
27+
RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
28+
-----END CERTIFICATE-----

ext/openssl/tests/cve2013_4073.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
CVE 2013-4073: Null-byte certificate handling
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("openssl")) die("skip");
6+
--FILE--
7+
<?php
8+
$cert = file_get_contents(__DIR__ . '/cve2013_4073.pem');
9+
$info = openssl_x509_parse($cert);
10+
var_export($info['extensions']);
11+
12+
--EXPECTF--
13+
array (
14+
'basicConstraints' => 'CA:FALSE',
15+
'subjectKeyIdentifier' => '88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C',
16+
'keyUsage' => 'Digital Signature, Non Repudiation, Key Encipherment',
17+
'subjectAltName' => 'DNS:altnull.python.org' . "\0" . 'example.com, email:[email protected]' . "\0" . '[email protected], 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
18+
',
19+
)

0 commit comments

Comments
 (0)