Commit 4d544e43c44 for php.net
commit 4d544e43c4429f5a17c4cdad75613686eac260ff
Merge: 1c941755f8a 4a16d22970b
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date: Fri Apr 3 22:43:53 2026 +0200
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
openssl: Fix error propagation in csr exports (#21403)
openssl: Fix missing error propagation in openssl_x509_export() (#21375)
Fix SKIPIF of openssl_password.phpt (#20941)
diff --cc ext/openssl/openssl.c
index ad2457672d0,22f25a48eed..f33e3bcf299
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@@ -1573,52 -2920,274 +1572,52 @@@ cleanup
/* {{{ x509 CSR functions */
-static zend_result php_openssl_csr_add_subj_entry(zval *item, X509_NAME *subj, int nid)
+/* {{{ Exports a CSR to file */
+PHP_FUNCTION(openssl_csr_export_to_file)
{
- 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;
-}
+ X509_REQ *csr;
+ zend_object *csr_obj;
+ zend_string *csr_str;
+ bool notext = 1;
+ char * filename = NULL;
+ size_t filename_len;
+ char file_path[MAXPATHLEN];
+ BIO * bio_out;
-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;
+ ZEND_PARSE_PARAMETERS_START(2, 3)
+ Z_PARAM_OBJ_OF_CLASS_OR_STR(csr_obj, php_openssl_request_ce, csr_str)
+ Z_PARAM_PATH(filename, filename_len)
+ Z_PARAM_OPTIONAL
+ Z_PARAM_BOOL(notext)
+ ZEND_PARSE_PARAMETERS_END();
- dn_sect = NCONF_get_string(req->req_config, req->section_name, "distinguished_name");
- if (dn_sect == NULL) {
- php_openssl_store_errors();
- return FAILURE;
+ RETVAL_FALSE;
+
+ csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
+ if (csr == NULL) {
+ php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved");
+ return;
}
- dn_sk = NCONF_get_section(req->req_config, dn_sect);
- if (dn_sk == NULL) {
- php_openssl_store_errors();
- return FAILURE;
+
+ if (!php_openssl_check_path(filename, filename_len, file_path, 2)) {
+ goto exit_cleanup;
}
- attr_sect = php_openssl_conf_get_string(req->req_config, req->section_name, "attributes");
- if (attr_sect == NULL) {
- attr_sk = NULL;
- } else {
- attr_sk = NCONF_get_section(req->req_config, attr_sect);
- if (attr_sk == NULL) {
+
+ bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY));
+ if (bio_out != NULL) {
+ if (!notext && !X509_REQ_print(bio_out, csr)) {
++ /* TODO: warn? */
php_openssl_store_errors();
- }
- if (!PEM_write_bio_X509_REQ(bio_out, csr)) {
- return FAILURE;
++ } else if (!PEM_write_bio_X509_REQ(bio_out, csr)) {
+ php_error_docref(NULL, E_WARNING, "Error writing PEM to file %s", file_path);
+ php_openssl_store_errors();
+ } else {
+ RETVAL_TRUE;
}
- }
- /* 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, *subitem;
- zend_string *strindex = NULL;
-
- subj = X509_REQ_get_subject_name(csr);
- /* apply values from the dn hash */
- ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(dn), strindex, item) {
- if (strindex) {
- int nid = OBJ_txt2nid(ZSTR_VAL(strindex));
- if (nid != NID_undef) {
- 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;
- }
- } else {
- php_error_docref(NULL, E_WARNING, "dn: %s is not a recognized name", ZSTR_VAL(strindex));
- }
- }
- } ZEND_HASH_FOREACH_END();
-
- /* Finally apply defaults from config file */
- for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
- size_t len;
- char buffer[200 + 1]; /*200 + \0 !*/
-
- v = sk_CONF_VALUE_value(dn_sk, i);
- type = v->name;
-
- len = strlen(type);
- if (len < sizeof("_default")) {
- continue;
- }
- len -= sizeof("_default") - 1;
- if (strcmp("_default", type + len) != 0) {
- continue;
- }
- if (len > 200) {
- len = 200;
- }
- memcpy(buffer, type, len);
- buffer[len] = '\0';
- type = buffer;
-
- /* Skip past any leading X. X: X, etc to allow for multiple
- * instances */
- for (str = type; *str; str++) {
- if (*str == ':' || *str == ',' || *str == '.') {
- str++;
- if (*str) {
- type = str;
- }
- break;
- }
- }
- /* if it is already set, skip this */
- nid = OBJ_txt2nid(type);
- if (X509_NAME_get_index_by_NID(subj, nid, -1) >= 0) {
- continue;
- }
- if (!X509_NAME_add_entry_by_txt(subj, type, MBSTRING_UTF8, (unsigned char*)v->value, -1, -1, 0)) {
- php_openssl_store_errors();
- php_error_docref(NULL, E_WARNING, "add_entry_by_txt %s -> %s (failed)", type, v->value);
- return FAILURE;
- }
- if (!X509_NAME_entry_count(subj)) {
- php_error_docref(NULL, E_WARNING, "No objects specified in config file");
- return FAILURE;
- }
- }
- if (attribs) {
- ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(attribs), strindex, item) {
- int nid;
-
- if (NULL == strindex) {
- php_error_docref(NULL, E_WARNING, "attributes: numeric fild names are not supported");
- continue;
- }
-
- 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_REQ_add1_attr_by_NID(csr, nid, MBSTRING_UTF8, (unsigned char*)ZSTR_VAL(str_item), (int)ZSTR_LEN(str_item))) {
- php_openssl_store_errors();
- php_error_docref(NULL, E_WARNING, "attributes: add_attr_by_NID %d -> %s (failed)", nid, ZSTR_VAL(str_item));
- zend_string_release(str_item);
- return FAILURE;
- }
- zend_string_release(str_item);
- } else {
- php_error_docref(NULL, E_WARNING, "attributes: %s is not a recognized attribute name", ZSTR_VAL(strindex));
- }
- } ZEND_HASH_FOREACH_END();
- for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
- v = sk_CONF_VALUE_value(attr_sk, i);
- /* if it is already set, skip this */
- nid = OBJ_txt2nid(v->name);
- if (X509_REQ_get_attr_by_NID(csr, nid, -1) >= 0) {
- continue;
- }
- if (!X509_REQ_add1_attr_by_txt(csr, v->name, MBSTRING_UTF8, (unsigned char*)v->value, -1)) {
- php_openssl_store_errors();
- php_error_docref(NULL, E_WARNING,
- "add1_attr_by_txt %s -> %s (failed; check error queue "
- "and value of string_mask OpenSSL option if illegal "
- "characters are reported)",
- v->name, v->value);
- return FAILURE;
- }
- }
- }
- } else {
- php_openssl_store_errors();
- }
-
- if (!X509_REQ_set_pubkey(csr, req->priv_key)) {
- php_openssl_store_errors();
- }
- return SUCCESS;
-}
-
-static X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num)
-{
- X509_REQ * csr = NULL;
- char file_path[MAXPATHLEN];
- BIO * in;
-
- if (ZSTR_LEN(csr_str) > 7 && memcmp(ZSTR_VAL(csr_str), "file://", sizeof("file://") - 1) == 0) {
- if (!php_openssl_check_path_str(csr_str, file_path, arg_num)) {
- return NULL;
- }
- in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
- } else {
- in = BIO_new_mem_buf(ZSTR_VAL(csr_str), (int) ZSTR_LEN(csr_str));
- }
-
- if (in == NULL) {
- php_openssl_store_errors();
- return NULL;
- }
-
- csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL);
- if (csr == NULL) {
- php_openssl_store_errors();
- }
-
- BIO_free(in);
-
- return csr;
-}
-
-static X509_REQ *php_openssl_csr_from_param(
- zend_object *csr_obj, zend_string *csr_str, uint32_t arg_num)
-{
- if (csr_obj) {
- return php_openssl_request_from_obj(csr_obj)->csr;
- }
-
- ZEND_ASSERT(csr_str);
-
- return php_openssl_csr_from_str(csr_str, arg_num);
-}
-
-/* {{{ Exports a CSR to file */
-PHP_FUNCTION(openssl_csr_export_to_file)
-{
- X509_REQ *csr;
- zend_object *csr_obj;
- zend_string *csr_str;
- bool notext = 1;
- char * filename = NULL;
- size_t filename_len;
- char file_path[MAXPATHLEN];
- BIO * bio_out;
-
- ZEND_PARSE_PARAMETERS_START(2, 3)
- Z_PARAM_OBJ_OF_CLASS_OR_STR(csr_obj, php_openssl_request_ce, csr_str)
- Z_PARAM_PATH(filename, filename_len)
- Z_PARAM_OPTIONAL
- Z_PARAM_BOOL(notext)
- ZEND_PARSE_PARAMETERS_END();
-
- RETVAL_FALSE;
-
- csr = php_openssl_csr_from_param(csr_obj, csr_str, 1);
- if (csr == NULL) {
- php_error_docref(NULL, E_WARNING, "X.509 Certificate Signing Request cannot be retrieved");
- return;
- }
-
- if (!php_openssl_check_path(filename, filename_len, file_path, 2)) {
- goto exit_cleanup;
- }
-
- bio_out = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_W(PKCS7_BINARY));
- if (bio_out != NULL) {
- if (!notext && !X509_REQ_print(bio_out, csr)) {
- /* TODO: warn? */
- php_openssl_store_errors();
- } else if (!PEM_write_bio_X509_REQ(bio_out, csr)) {
- php_error_docref(NULL, E_WARNING, "Error writing PEM to file %s", file_path);
- php_openssl_store_errors();
- } else {
- RETVAL_TRUE;
- }
- BIO_free(bio_out);
- } else {
- php_openssl_store_errors();
- php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path);
+ BIO_free(bio_out);
+ } else {
+ php_openssl_store_errors();
+ php_error_docref(NULL, E_WARNING, "Error opening file %s", file_path);
}
exit_cleanup: