Line 0
Link Here
|
|
|
1 |
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c |
2 |
index d7ac117..c32748c 100644 |
3 |
--- ext/openssl/openssl.c |
4 |
+++ ext/openssl/openssl.c |
5 |
@@ -1398,6 +1398,74 @@ PHP_FUNCTION(openssl_x509_check_private_key) |
6 |
} |
7 |
/* }}} */ |
8 |
|
9 |
+/* Special handling of subjectAltName, see CVE-2013-4073 |
10 |
+ * Christian Heimes |
11 |
+ */ |
12 |
+ |
13 |
+static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) |
14 |
+{ |
15 |
+ GENERAL_NAMES *names; |
16 |
+ const X509V3_EXT_METHOD *method = NULL; |
17 |
+ long i, length, num; |
18 |
+ const unsigned char *p; |
19 |
+ |
20 |
+ method = X509V3_EXT_get(extension); |
21 |
+ if (method == NULL) { |
22 |
+ return -1; |
23 |
+ } |
24 |
+ |
25 |
+ p = extension->value->data; |
26 |
+ length = extension->value->length; |
27 |
+ if (method->it) { |
28 |
+ names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length, |
29 |
+ ASN1_ITEM_ptr(method->it))); |
30 |
+ } else { |
31 |
+ names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length)); |
32 |
+ } |
33 |
+ if (names == NULL) { |
34 |
+ return -1; |
35 |
+ } |
36 |
+ |
37 |
+ num = sk_GENERAL_NAME_num(names); |
38 |
+ for (i = 0; i < num; i++) { |
39 |
+ GENERAL_NAME *name; |
40 |
+ ASN1_STRING *as; |
41 |
+ name = sk_GENERAL_NAME_value(names, i); |
42 |
+ switch (name->type) { |
43 |
+ case GEN_EMAIL: |
44 |
+ BIO_puts(bio, "email:"); |
45 |
+ as = name->d.rfc822Name; |
46 |
+ BIO_write(bio, ASN1_STRING_data(as), |
47 |
+ ASN1_STRING_length(as)); |
48 |
+ break; |
49 |
+ case GEN_DNS: |
50 |
+ BIO_puts(bio, "DNS:"); |
51 |
+ as = name->d.dNSName; |
52 |
+ BIO_write(bio, ASN1_STRING_data(as), |
53 |
+ ASN1_STRING_length(as)); |
54 |
+ break; |
55 |
+ case GEN_URI: |
56 |
+ BIO_puts(bio, "URI:"); |
57 |
+ as = name->d.uniformResourceIdentifier; |
58 |
+ BIO_write(bio, ASN1_STRING_data(as), |
59 |
+ ASN1_STRING_length(as)); |
60 |
+ break; |
61 |
+ default: |
62 |
+ /* use builtin print for GEN_OTHERNAME, GEN_X400, |
63 |
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID |
64 |
+ */ |
65 |
+ GENERAL_NAME_print(bio, name); |
66 |
+ } |
67 |
+ /* trailing ', ' except for last element */ |
68 |
+ if (i < (num - 1)) { |
69 |
+ BIO_puts(bio, ", "); |
70 |
+ } |
71 |
+ } |
72 |
+ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); |
73 |
+ |
74 |
+ return 0; |
75 |
+} |
76 |
+ |
77 |
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true]) |
78 |
Returns an array of the fields/values of the CERT */ |
79 |
PHP_FUNCTION(openssl_x509_parse) |
80 |
@@ -1494,15 +1562,29 @@ PHP_FUNCTION(openssl_x509_parse) |
81 |
|
82 |
|
83 |
for (i = 0; i < X509_get_ext_count(cert); i++) { |
84 |
+ int nid; |
85 |
extension = X509_get_ext(cert, i); |
86 |
- if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) { |
87 |
+ nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); |
88 |
+ if (nid != NID_undef) { |
89 |
extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension))); |
90 |
} else { |
91 |
OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1); |
92 |
extname = buf; |
93 |
} |
94 |
bio_out = BIO_new(BIO_s_mem()); |
95 |
- if (X509V3_EXT_print(bio_out, extension, 0, 0)) { |
96 |
+ if (nid == NID_subject_alt_name) { |
97 |
+ if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) { |
98 |
+ add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); |
99 |
+ } else { |
100 |
+ zval_dtor(return_value); |
101 |
+ if (certresource == -1 && cert) { |
102 |
+ X509_free(cert); |
103 |
+ } |
104 |
+ BIO_free(bio_out); |
105 |
+ RETURN_FALSE; |
106 |
+ } |
107 |
+ } |
108 |
+ else if (X509V3_EXT_print(bio_out, extension, 0, 0)) { |
109 |
BIO_get_mem_ptr(bio_out, &bio_buf); |
110 |
add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); |
111 |
} else { |