From 48ebe588cd18867ead009576c0cdbaa29e953398 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Wed, 20 Dec 2023 16:11:30 +0000 Subject: [PATCH] Implement request #48520: openssl_csr_new should allow multiple values/fields in dn Closes GH-12984 --- NEWS | 2 ++ UPGRADING | 2 ++ ext/openssl/openssl.c | 61 +++++++++++++++++++++++++------------------ 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/NEWS b/NEWS index 23dffc319812e..087d98c2c68eb 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,8 @@ Opcache: OpenSSL: . Fixed bug #80269 (OpenSSL sets Subject wrong with extraattribs parameter). (Jakub Zelenka) + . Implement request #48520 (openssl_csr_new - allow multiple values in DN). + (Jakub Zelenka) PDO: . Fixed setAttribute and getAttribute (SakiTakamachi) diff --git a/UPGRADING b/UPGRADING index 589ad4e0afc1f..cc278ac22e92f 100644 --- a/UPGRADING +++ b/UPGRADING @@ -229,6 +229,8 @@ PHP 8.4 UPGRADE NOTES - OpenSSL: . The extra_attributes parameter in openssl_csr_new sets CSR attributes instead of subject DN which was incorrectly done previously. + . The dn parameter in openssl_csr_new allows setting array of values for + a single entry. - PDO: . getAttribute, enabled to get the value of ATTR_STRINGIFY_FETCHES. diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 0ccb3e4c7e08f..9a3f36b14ea3e 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2863,8 +2863,29 @@ PHP_FUNCTION(openssl_pkcs12_read) /* {{{ x509 CSR functions */ -/* {{{ php_openssl_make_REQ */ -static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, zval * dn, zval * attribs) +static zend_result php_openssl_csr_add_subj_entry(zval *item, X509_NAME *subj, int nid) +{ + zend_string *str_item = zval_try_get_string(item); + if (UNEXPECTED(!str_item)) { + return FAILURE; + } + if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, + (unsigned char*)ZSTR_VAL(str_item), -1, -1, 0)) + { + php_openssl_store_errors(); + php_error_docref(NULL, E_WARNING, + "dn: add_entry_by_NID %d -> %s (failed; check error" + " queue and value of string_mask OpenSSL option " + "if illegal characters are reported)", + nid, ZSTR_VAL(str_item)); + zend_string_release(str_item); + return FAILURE; + } + zend_string_release(str_item); + return SUCCESS; +} + +static zend_result php_openssl_csr_make(struct php_x509_request * req, X509_REQ * csr, zval * dn, zval * attribs) { STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL; char * str, *dn_sect, *attr_sect; @@ -2892,11 +2913,11 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z /* setup the version number: version 1 */ if (X509_REQ_set_version(csr, 0L)) { int i, nid; - char * type; - CONF_VALUE * v; - X509_NAME * subj; - zval * item; - zend_string * strindex = NULL; + char *type; + CONF_VALUE *v; + X509_NAME *subj; + zval *item, *subitem; + zend_string *strindex = NULL; subj = X509_REQ_get_subject_name(csr); /* apply values from the dn hash */ @@ -2904,23 +2925,15 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z if (strindex) { int nid = OBJ_txt2nid(ZSTR_VAL(strindex)); if (nid != NID_undef) { - zend_string *str_item = zval_try_get_string(item); - if (UNEXPECTED(!str_item)) { - return FAILURE; - } - if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8, - (unsigned char*)ZSTR_VAL(str_item), -1, -1, 0)) - { - php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, - "dn: add_entry_by_NID %d -> %s (failed; check error" - " queue and value of string_mask OpenSSL option " - "if illegal characters are reported)", - nid, ZSTR_VAL(str_item)); - zend_string_release(str_item); + if (Z_TYPE_P(item) == IS_ARRAY) { + ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(item), i, subitem) { + if (php_openssl_csr_add_subj_entry(subitem, subj, nid) == FAILURE) { + return FAILURE; + } + } ZEND_HASH_FOREACH_END(); + } else if (php_openssl_csr_add_subj_entry(item, subj, nid) == FAILURE) { return FAILURE; } - zend_string_release(str_item); } else { php_error_docref(NULL, E_WARNING, "dn: %s is not a recognized name", ZSTR_VAL(strindex)); } @@ -3029,8 +3042,6 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z } return SUCCESS; } -/* }}} */ - static X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num) { @@ -3370,7 +3381,7 @@ PHP_FUNCTION(openssl_csr_new) } else { csr = X509_REQ_new(); if (csr) { - if (php_openssl_make_REQ(&req, csr, dn, attribs) == SUCCESS) { + if (php_openssl_csr_make(&req, csr, dn, attribs) == SUCCESS) { X509V3_CTX ext_ctx; X509V3_set_ctx(&ext_ctx, NULL, NULL, csr, NULL, 0);