|
|
af9dc8 |
From 2874696a5a8d46639d261571f915c493cd875897 Mon Sep 17 00:00:00 2001
|
|
|
af9dc8 |
From: Stanislav Malyshev <stas@php.net>
|
|
|
af9dc8 |
Date: Tue, 13 Aug 2013 22:20:33 -0700
|
|
|
af9dc8 |
Subject: [PATCH] Fix CVE-2013-4073 - handling of certs with null bytes
|
|
|
af9dc8 |
|
|
|
af9dc8 |
---
|
|
|
af9dc8 |
NEWS | 4 ++
|
|
|
af9dc8 |
ext/openssl/openssl.c | 86 ++++++++++++++++++++++++++++++++++++-
|
|
|
af9dc8 |
ext/openssl/tests/cve2013_4073.pem | 28 ++++++++++++
|
|
|
af9dc8 |
ext/openssl/tests/cve2013_4073.phpt | 19 ++++++++
|
|
|
af9dc8 |
4 files changed, 135 insertions(+), 2 deletions(-)
|
|
|
af9dc8 |
create mode 100644 ext/openssl/tests/cve2013_4073.pem
|
|
|
af9dc8 |
create mode 100644 ext/openssl/tests/cve2013_4073.phpt
|
|
|
af9dc8 |
|
|
|
af9dc8 |
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
|
|
|
af9dc8 |
index d7ac117..c32748c 100644
|
|
|
af9dc8 |
--- a/ext/openssl/openssl.c
|
|
|
af9dc8 |
+++ b/ext/openssl/openssl.c
|
|
|
af9dc8 |
@@ -1398,6 +1398,74 @@ PHP_FUNCTION(openssl_x509_check_private_key)
|
|
|
af9dc8 |
}
|
|
|
af9dc8 |
/* }}} */
|
|
|
af9dc8 |
|
|
|
af9dc8 |
+/* Special handling of subjectAltName, see CVE-2013-4073
|
|
|
af9dc8 |
+ * Christian Heimes
|
|
|
af9dc8 |
+ */
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension)
|
|
|
af9dc8 |
+{
|
|
|
af9dc8 |
+ GENERAL_NAMES *names;
|
|
|
af9dc8 |
+ const X509V3_EXT_METHOD *method = NULL;
|
|
|
af9dc8 |
+ long i, length, num;
|
|
|
af9dc8 |
+ const unsigned char *p;
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+ method = X509V3_EXT_get(extension);
|
|
|
af9dc8 |
+ if (method == NULL) {
|
|
|
af9dc8 |
+ return -1;
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+ p = extension->value->data;
|
|
|
af9dc8 |
+ length = extension->value->length;
|
|
|
af9dc8 |
+ if (method->it) {
|
|
|
af9dc8 |
+ names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length,
|
|
|
af9dc8 |
+ ASN1_ITEM_ptr(method->it)));
|
|
|
af9dc8 |
+ } else {
|
|
|
af9dc8 |
+ names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length));
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ if (names == NULL) {
|
|
|
af9dc8 |
+ return -1;
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+ num = sk_GENERAL_NAME_num(names);
|
|
|
af9dc8 |
+ for (i = 0; i < num; i++) {
|
|
|
af9dc8 |
+ GENERAL_NAME *name;
|
|
|
af9dc8 |
+ ASN1_STRING *as;
|
|
|
af9dc8 |
+ name = sk_GENERAL_NAME_value(names, i);
|
|
|
af9dc8 |
+ switch (name->type) {
|
|
|
af9dc8 |
+ case GEN_EMAIL:
|
|
|
af9dc8 |
+ BIO_puts(bio, "email:");
|
|
|
af9dc8 |
+ as = name->d.rfc822Name;
|
|
|
af9dc8 |
+ BIO_write(bio, ASN1_STRING_data(as),
|
|
|
af9dc8 |
+ ASN1_STRING_length(as));
|
|
|
af9dc8 |
+ break;
|
|
|
af9dc8 |
+ case GEN_DNS:
|
|
|
af9dc8 |
+ BIO_puts(bio, "DNS:");
|
|
|
af9dc8 |
+ as = name->d.dNSName;
|
|
|
af9dc8 |
+ BIO_write(bio, ASN1_STRING_data(as),
|
|
|
af9dc8 |
+ ASN1_STRING_length(as));
|
|
|
af9dc8 |
+ break;
|
|
|
af9dc8 |
+ case GEN_URI:
|
|
|
af9dc8 |
+ BIO_puts(bio, "URI:");
|
|
|
af9dc8 |
+ as = name->d.uniformResourceIdentifier;
|
|
|
af9dc8 |
+ BIO_write(bio, ASN1_STRING_data(as),
|
|
|
af9dc8 |
+ ASN1_STRING_length(as));
|
|
|
af9dc8 |
+ break;
|
|
|
af9dc8 |
+ default:
|
|
|
af9dc8 |
+ /* use builtin print for GEN_OTHERNAME, GEN_X400,
|
|
|
af9dc8 |
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
|
|
|
af9dc8 |
+ */
|
|
|
af9dc8 |
+ GENERAL_NAME_print(bio, name);
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ /* trailing ', ' except for last element */
|
|
|
af9dc8 |
+ if (i < (num - 1)) {
|
|
|
af9dc8 |
+ BIO_puts(bio, ", ");
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+ return 0;
|
|
|
af9dc8 |
+}
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])
|
|
|
af9dc8 |
Returns an array of the fields/values of the CERT */
|
|
|
af9dc8 |
PHP_FUNCTION(openssl_x509_parse)
|
|
|
af9dc8 |
@@ -1494,15 +1562,29 @@ PHP_FUNCTION(openssl_x509_parse)
|
|
|
af9dc8 |
|
|
|
af9dc8 |
|
|
|
af9dc8 |
for (i = 0; i < X509_get_ext_count(cert); i++) {
|
|
|
af9dc8 |
+ int nid;
|
|
|
af9dc8 |
extension = X509_get_ext(cert, i);
|
|
|
af9dc8 |
- if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) {
|
|
|
af9dc8 |
+ nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension));
|
|
|
af9dc8 |
+ if (nid != NID_undef) {
|
|
|
af9dc8 |
extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension)));
|
|
|
af9dc8 |
} else {
|
|
|
af9dc8 |
OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1);
|
|
|
af9dc8 |
extname = buf;
|
|
|
af9dc8 |
}
|
|
|
af9dc8 |
bio_out = BIO_new(BIO_s_mem());
|
|
|
af9dc8 |
- if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
|
|
|
af9dc8 |
+ if (nid == NID_subject_alt_name) {
|
|
|
af9dc8 |
+ if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
|
|
|
af9dc8 |
+ add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
|
|
|
af9dc8 |
+ } else {
|
|
|
af9dc8 |
+ zval_dtor(return_value);
|
|
|
af9dc8 |
+ if (certresource == -1 && cert) {
|
|
|
af9dc8 |
+ X509_free(cert);
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ BIO_free(bio_out);
|
|
|
af9dc8 |
+ RETURN_FALSE;
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ }
|
|
|
af9dc8 |
+ else if (X509V3_EXT_print(bio_out, extension, 0, 0)) {
|
|
|
af9dc8 |
BIO_get_mem_ptr(bio_out, &bio_buf);
|
|
|
af9dc8 |
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
|
|
|
af9dc8 |
} else {
|
|
|
af9dc8 |
diff --git a/ext/openssl/tests/cve2013_4073.pem b/ext/openssl/tests/cve2013_4073.pem
|
|
|
af9dc8 |
new file mode 100644
|
|
|
af9dc8 |
index 0000000..7ebb994
|
|
|
af9dc8 |
--- /dev/null
|
|
|
af9dc8 |
+++ b/ext/openssl/tests/cve2013_4073.pem
|
|
|
af9dc8 |
@@ -0,0 +1,28 @@
|
|
|
af9dc8 |
+-----BEGIN CERTIFICATE-----
|
|
|
af9dc8 |
+MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx
|
|
|
af9dc8 |
+DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ
|
|
|
af9dc8 |
+eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg
|
|
|
af9dc8 |
+RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y
|
|
|
af9dc8 |
+ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw
|
|
|
af9dc8 |
+NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
|
|
|
af9dc8 |
+DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv
|
|
|
af9dc8 |
+ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt
|
|
|
af9dc8 |
+ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq
|
|
|
af9dc8 |
+hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB
|
|
|
af9dc8 |
+BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j
|
|
|
af9dc8 |
+pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P
|
|
|
af9dc8 |
+vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv
|
|
|
af9dc8 |
+KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA
|
|
|
af9dc8 |
+oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL
|
|
|
af9dc8 |
+08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV
|
|
|
af9dc8 |
+HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E
|
|
|
af9dc8 |
+BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu
|
|
|
af9dc8 |
+Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251
|
|
|
af9dc8 |
+bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA
|
|
|
af9dc8 |
+AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9
|
|
|
af9dc8 |
+i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j
|
|
|
af9dc8 |
+HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk
|
|
|
af9dc8 |
+kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx
|
|
|
af9dc8 |
+VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW
|
|
|
af9dc8 |
+RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ=
|
|
|
af9dc8 |
+-----END CERTIFICATE-----
|
|
|
af9dc8 |
diff --git a/ext/openssl/tests/cve2013_4073.phpt b/ext/openssl/tests/cve2013_4073.phpt
|
|
|
af9dc8 |
new file mode 100644
|
|
|
af9dc8 |
index 0000000..e676ddf
|
|
|
af9dc8 |
--- /dev/null
|
|
|
af9dc8 |
+++ b/ext/openssl/tests/cve2013_4073.phpt
|
|
|
af9dc8 |
@@ -0,0 +1,19 @@
|
|
|
af9dc8 |
+--TEST--
|
|
|
af9dc8 |
+CVE 2013-4073: Null-byte certificate handling
|
|
|
af9dc8 |
+--SKIPIF--
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+if (!extension_loaded("openssl")) die("skip");
|
|
|
af9dc8 |
+--FILE--
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+$cert = file_get_contents(__DIR__ . '/cve2013_4073.pem');
|
|
|
af9dc8 |
+$info = openssl_x509_parse($cert);
|
|
|
af9dc8 |
+var_export($info['extensions']);
|
|
|
af9dc8 |
+
|
|
|
af9dc8 |
+--EXPECTF--
|
|
|
af9dc8 |
+array (
|
|
|
af9dc8 |
+ 'basicConstraints' => 'CA:FALSE',
|
|
|
af9dc8 |
+ 'subjectKeyIdentifier' => '88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C',
|
|
|
af9dc8 |
+ 'keyUsage' => 'Digital Signature, Non Repudiation, Key Encipherment',
|
|
|
af9dc8 |
+ '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
|
|
|
af9dc8 |
+',
|
|
|
af9dc8 |
+)
|
|
|
af9dc8 |
--
|
|
|
af9dc8 |
1.7.11.5
|
|
|
af9dc8 |
|
|
|
af9dc8 |
From c1c49d6e3983c9ce0b43ffe7bf6e03b809ed048b Mon Sep 17 00:00:00 2001
|
|
|
af9dc8 |
From: Stanislav Malyshev <stas@php.net>
|
|
|
af9dc8 |
Date: Mon, 19 Aug 2013 01:02:12 -0700
|
|
|
af9dc8 |
Subject: [PATCH] fix using wrong buffer pointer
|
|
|
af9dc8 |
|
|
|
af9dc8 |
---
|
|
|
af9dc8 |
ext/openssl/openssl.c | 1 +
|
|
|
af9dc8 |
1 file changed, 1 insertion(+)
|
|
|
af9dc8 |
|
|
|
af9dc8 |
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
|
|
|
af9dc8 |
index c7a9f5c..e7672e4 100644
|
|
|
af9dc8 |
--- a/ext/openssl/openssl.c
|
|
|
af9dc8 |
+++ b/ext/openssl/openssl.c
|
|
|
af9dc8 |
@@ -1502,6 +1502,7 @@ PHP_FUNCTION(openssl_x509_parse)
|
|
|
af9dc8 |
bio_out = BIO_new(BIO_s_mem());
|
|
|
af9dc8 |
if (nid == NID_subject_alt_name) {
|
|
|
af9dc8 |
if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) {
|
|
|
af9dc8 |
+ BIO_get_mem_ptr(bio_out, &bio_buf);
|
|
|
af9dc8 |
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1);
|
|
|
af9dc8 |
} else {
|
|
|
af9dc8 |
zval_dtor(return_value);
|
|
|
af9dc8 |
--
|
|
|
af9dc8 |
1.7.11.5
|
|
|
af9dc8 |
|