|
|
| version 1.1.1.3, 2013/07/22 01:31:57 | version 1.1.1.4, 2013/10/14 08:02:27 |
|---|---|
| Line 561 static EVP_PKEY * php_openssl_generate_private_key(str | Line 561 static EVP_PKEY * php_openssl_generate_private_key(str |
| static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */ | static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int shortname TSRMLS_DC) /* {{{ */ |
| { | { |
| zval **data; | |
| zval *subitem, *subentries; | zval *subitem, *subentries; |
| int i, j = -1, last = -1, obj_cnt = 0; | int i, j = -1, last = -1, obj_cnt = 0; |
| char *sname; | char *sname; |
| Line 578 static void add_assoc_name_entry(zval * val, char * ke | Line 579 static void add_assoc_name_entry(zval * val, char * ke |
| for (i = 0; i < X509_NAME_entry_count(name); i++) { | for (i = 0; i < X509_NAME_entry_count(name); i++) { |
| unsigned char *to_add; | unsigned char *to_add; |
| int to_add_len; | int to_add_len = 0; |
| ne = X509_NAME_get_entry(name, i); | ne = X509_NAME_get_entry(name, i); |
| Line 592 static void add_assoc_name_entry(zval * val, char * ke | Line 593 static void add_assoc_name_entry(zval * val, char * ke |
| sname = (char *) OBJ_nid2ln(nid); | sname = (char *) OBJ_nid2ln(nid); |
| } | } |
| MAKE_STD_ZVAL(subentries); | str = X509_NAME_ENTRY_get_data(ne); |
| array_init(subentries); | if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) { |
| to_add_len = ASN1_STRING_to_UTF8(&to_add, str); | |
| } else { | |
| to_add = ASN1_STRING_data(str); | |
| to_add_len = ASN1_STRING_length(str); | |
| } | |
| last = -1; | if (to_add_len != -1) { |
| for (;;) { | if (zend_hash_find(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, (void**)&data) == SUCCESS) { |
| j = X509_NAME_get_index_by_OBJ(name, obj, last); | if (Z_TYPE_PP(data) == IS_ARRAY) { |
| if (j < 0) { | subentries = *data; |
| if (last != -1) break; | |
| } else { | |
| obj_cnt++; | |
| ne = X509_NAME_get_entry(name, j); | |
| str = X509_NAME_ENTRY_get_data(ne); | |
| if (ASN1_STRING_type(str) != V_ASN1_UTF8STRING) { | |
| to_add_len = ASN1_STRING_to_UTF8(&to_add, str); | |
| if (to_add_len != -1) { | |
| add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); | |
| } | |
| } else { | |
| to_add = ASN1_STRING_data(str); | |
| to_add_len = ASN1_STRING_length(str); | |
| add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); | add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); |
| } else if (Z_TYPE_PP(data) == IS_STRING) { | |
| MAKE_STD_ZVAL(subentries); | |
| array_init(subentries); | |
| add_next_index_stringl(subentries, Z_STRVAL_PP(data), Z_STRLEN_PP(data), 1); | |
| add_next_index_stringl(subentries, (char *)to_add, to_add_len, 1); | |
| zend_hash_update(Z_ARRVAL_P(subitem), sname, strlen(sname)+1, &subentries, sizeof(zval*), NULL); | |
| } | } |
| } | } else { |
| last = j; | |
| } | |
| i = last; | |
| if (obj_cnt > 1) { | |
| add_assoc_zval_ex(subitem, sname, strlen(sname) + 1, subentries); | |
| } else { | |
| zval_dtor(subentries); | |
| FREE_ZVAL(subentries); | |
| if (obj_cnt && str && to_add_len > -1) { | |
| add_assoc_stringl(subitem, sname, (char *)to_add, to_add_len, 1); | add_assoc_stringl(subitem, sname, (char *)to_add, to_add_len, 1); |
| } | } |
| } | } |
| Line 1398 PHP_FUNCTION(openssl_x509_check_private_key) | Line 1387 PHP_FUNCTION(openssl_x509_check_private_key) |
| } | } |
| /* }}} */ | /* }}} */ |
| /* Special handling of subjectAltName, see CVE-2013-4073 | |
| * Christian Heimes | |
| */ | |
| static int openssl_x509v3_subjectAltName(BIO *bio, X509_EXTENSION *extension) | |
| { | |
| GENERAL_NAMES *names; | |
| const X509V3_EXT_METHOD *method = NULL; | |
| long i, length, num; | |
| const unsigned char *p; | |
| method = X509V3_EXT_get(extension); | |
| if (method == NULL) { | |
| return -1; | |
| } | |
| p = extension->value->data; | |
| length = extension->value->length; | |
| if (method->it) { | |
| names = (GENERAL_NAMES*)(ASN1_item_d2i(NULL, &p, length, | |
| ASN1_ITEM_ptr(method->it))); | |
| } else { | |
| names = (GENERAL_NAMES*)(method->d2i(NULL, &p, length)); | |
| } | |
| if (names == NULL) { | |
| return -1; | |
| } | |
| num = sk_GENERAL_NAME_num(names); | |
| for (i = 0; i < num; i++) { | |
| GENERAL_NAME *name; | |
| ASN1_STRING *as; | |
| name = sk_GENERAL_NAME_value(names, i); | |
| switch (name->type) { | |
| case GEN_EMAIL: | |
| BIO_puts(bio, "email:"); | |
| as = name->d.rfc822Name; | |
| BIO_write(bio, ASN1_STRING_data(as), | |
| ASN1_STRING_length(as)); | |
| break; | |
| case GEN_DNS: | |
| BIO_puts(bio, "DNS:"); | |
| as = name->d.dNSName; | |
| BIO_write(bio, ASN1_STRING_data(as), | |
| ASN1_STRING_length(as)); | |
| break; | |
| case GEN_URI: | |
| BIO_puts(bio, "URI:"); | |
| as = name->d.uniformResourceIdentifier; | |
| BIO_write(bio, ASN1_STRING_data(as), | |
| ASN1_STRING_length(as)); | |
| break; | |
| default: | |
| /* use builtin print for GEN_OTHERNAME, GEN_X400, | |
| * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID | |
| */ | |
| GENERAL_NAME_print(bio, name); | |
| } | |
| /* trailing ', ' except for last element */ | |
| if (i < (num - 1)) { | |
| BIO_puts(bio, ", "); | |
| } | |
| } | |
| sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); | |
| return 0; | |
| } | |
| /* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true]) | /* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true]) |
| Returns an array of the fields/values of the CERT */ | Returns an array of the fields/values of the CERT */ |
| PHP_FUNCTION(openssl_x509_parse) | PHP_FUNCTION(openssl_x509_parse) |
| Line 1494 PHP_FUNCTION(openssl_x509_parse) | Line 1551 PHP_FUNCTION(openssl_x509_parse) |
| for (i = 0; i < X509_get_ext_count(cert); i++) { | for (i = 0; i < X509_get_ext_count(cert); i++) { |
| int nid; | |
| extension = X509_get_ext(cert, i); | extension = X509_get_ext(cert, i); |
| if (OBJ_obj2nid(X509_EXTENSION_get_object(extension)) != NID_undef) { | nid = OBJ_obj2nid(X509_EXTENSION_get_object(extension)); |
| if (nid != NID_undef) { | |
| extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension))); | extname = (char *)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(extension))); |
| } else { | } else { |
| OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1); | OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1); |
| extname = buf; | extname = buf; |
| } | } |
| bio_out = BIO_new(BIO_s_mem()); | bio_out = BIO_new(BIO_s_mem()); |
| if (X509V3_EXT_print(bio_out, extension, 0, 0)) { | if (nid == NID_subject_alt_name) { |
| if (openssl_x509v3_subjectAltName(bio_out, extension) == 0) { | |
| BIO_get_mem_ptr(bio_out, &bio_buf); | |
| add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); | |
| } else { | |
| zval_dtor(return_value); | |
| if (certresource == -1 && cert) { | |
| X509_free(cert); | |
| } | |
| BIO_free(bio_out); | |
| RETURN_FALSE; | |
| } | |
| } | |
| else if (X509V3_EXT_print(bio_out, extension, 0, 0)) { | |
| BIO_get_mem_ptr(bio_out, &bio_buf); | BIO_get_mem_ptr(bio_out, &bio_buf); |
| add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); | add_assoc_stringl(subitem, extname, bio_buf->data, bio_buf->length, 1); |
| } else { | } else { |