Implement request #48520: openssl_csr_new should allow multiple values/fields in dn

Closes GH-12984
This commit is contained in:
Jakub Zelenka 2023-12-20 16:11:30 +00:00
parent e8fde6bd92
commit 48ebe588cd
No known key found for this signature in database
GPG Key ID: 1C0779DC5C0A9DE4
3 changed files with 40 additions and 25 deletions

2
NEWS
View File

@ -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)

View File

@ -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.

View File

@ -2863,8 +2863,29 @@ cleanup:
/* {{{ 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)) {
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;
}
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);
} 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);