Commit c1d2875a82e for php.net

commit c1d2875a82eec5a1884cdf9be742a832262622df
Author: Steve Wall <Stephen.Wall@redcom.com>
Date:   Wed Oct 1 16:47:50 2025 -0400

    Implement GH-20310: No critical extension indication in openssl_x509_parse() output

    This add criticalExtensions field to openssl_x509_parse() output that
    provides name of all critical extensions.

    Closes #20310
    Closes #20311

diff --git a/NEWS b/NEWS
index 67fdd2f098b..9c1fc8c14b0 100644
--- a/NEWS
+++ b/NEWS
@@ -53,6 +53,10 @@ PHP                                                                        NEWS
   . Fixed bug GH-20051 (apache2 shutdowns when restart is requested during
     preloading). (Arnaud, welcomycozyhom)

+- OpenSSL:
+  . Implemented GH-20310 (No critical extension indication in
+    openssl_x509_parse() output). (StephenWall)
+
 - PDO_PGSQL:
   . Clear session-local state disconnect-equivalent processing.
     (KentarouTakeda)
diff --git a/UPGRADING b/UPGRADING
index 338a3e5179a..a160f0c901a 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -70,6 +70,10 @@ PHP 8.6 UPGRADE NOTES
 5. Changed Functions
 ========================================

+- OpenSSL:
+  . Output of openssl_x509_parse() contains criticalExtensions listing all
+    critical certificate extensions.
+
 - Phar:
   . Phar::mungServer() now supports reference values.

diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 2c09b89e312..d00efbfe5c2 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -1003,6 +1003,8 @@ PHP_FUNCTION(openssl_x509_parse)
 	bool useshortnames = 1;
 	char * tmpstr;
 	zval subitem;
+	zval critext;
+	int critcount = 0;
 	X509_EXTENSION *extension;
 	X509_NAME *subject_name;
 	char *cert_name;
@@ -1115,18 +1117,22 @@ PHP_FUNCTION(openssl_x509_parse)
 	add_assoc_zval(return_value, "purposes", &subitem);

 	array_init(&subitem);
-
+	array_init(&critext);

 	for (i = 0; i < X509_get_ext_count(cert); i++) {
 		int nid;
 		extension = X509_get_ext(cert, i);
 		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(nid);
 		} else {
 			OBJ_obj2txt(buf, sizeof(buf)-1, X509_EXTENSION_get_object(extension), 1);
 			extname = buf;
 		}
+		if (X509_EXTENSION_get_critical(extension)) {
+			add_next_index_string(&critext, extname);
+			critcount++;
+		}
 		bio_out = BIO_new(BIO_s_mem());
 		if (bio_out == NULL) {
 			php_openssl_store_errors();
@@ -1150,6 +1156,11 @@ PHP_FUNCTION(openssl_x509_parse)
 		BIO_free(bio_out);
 	}
 	add_assoc_zval(return_value, "extensions", &subitem);
+	if (critcount > 0) {
+		add_assoc_zval(return_value, "criticalExtensions", &critext);
+	} else {
+		zval_ptr_dtor(&critext);
+	}
 	if (cert_str) {
 		X509_free(cert);
 	}
diff --git a/ext/openssl/tests/crit.crt b/ext/openssl/tests/crit.crt
new file mode 100644
index 00000000000..b56df4051d1
--- /dev/null
+++ b/ext/openssl/tests/crit.crt
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC4DCCAkmgAwIBAgIUXulKXzpxr33sV/2LwI0+yhpUAZgwDQYJKoZIhvcNAQEF
+BQAwgYExHjAcBgNVBAMMFUhlbnJpcXVlIGRvIE4uIEFuZ2VsbzELMAkGA1UEBhMC
+QlIxGjAYBgNVBAgMEVJpbyBHcmFuZGUgZG8gU3VsMRUwEwYDVQQHDAxQb3J0byBB
+bGVncmUxHzAdBgkqhkiG9w0BCQEWEGhuYW5nZWxvQHBocC5uZXQwHhcNMjUxMDAy
+MTgwNjMwWhcNMjYxMDAyMTgwNjMwWjCBgTEeMBwGA1UEAwwVSGVucmlxdWUgZG8g
+Ti4gQW5nZWxvMQswCQYDVQQGEwJCUjEaMBgGA1UECAwRUmlvIEdyYW5kZSBkbyBT
+dWwxFTATBgNVBAcMDFBvcnRvIEFsZWdyZTEfMB0GCSqGSIb3DQEJARYQaG5hbmdl
+bG9AcGhwLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAy16ej5ArW6Vf
+j9YMBUFh+hM9FPN7hJkvCBp6XiPBZPK2P7xzmc2WWsUQsPpaMnN+NqggyEIXjDgj
+ZuRZHr89Oqu+e/6KKIi0d8q8mBioihtSGSIqZZrbAveaCq81EipOtMLiNZm4KTFD
++Syov078XrOT5pFLV34ps9qoJHlHD6UCAwEAAaNTMFEwHQYDVR0OBBYEFNt+QHK9
+XDWF7CkpgRLoYmhqtz99MB8GA1UdIwQYMBaAFNt+QHK9XDWF7CkpgRLoYmhqtz99
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAc6jR36JD6xkzq2r0
+uIEjhiieDfFXcAVgisqymPHt6DDMSajRskfWPO58ayBKmT2J1yPxx2vdjAZxIRcg
+2a06ef2OxE62X4+WNm6skIKLCXmc3AgkT//cqCjOs54EQMpdCJ/mkkYo9gZMB1aQ
+jgozP+80FNIaioaDWVZsTsg3q0Q=
+-----END CERTIFICATE-----
diff --git a/ext/openssl/tests/openssl_x509_parse_basic.phpt b/ext/openssl/tests/openssl_x509_parse_basic.phpt
index ef63f0f85f4..7170b1a08ac 100644
--- a/ext/openssl/tests/openssl_x509_parse_basic.phpt
+++ b/ext/openssl/tests/openssl_x509_parse_basic.phpt
@@ -8,7 +8,7 @@
 ?>
 --FILE--
 <?php
-$cert = "file://" . __DIR__ . "/cert.crt";
+$cert = "file://" . __DIR__ . "/crit.crt";

 $parsedCert = openssl_x509_parse($cert);
 var_dump($parsedCert === openssl_x509_parse(openssl_x509_read($cert)));
@@ -17,19 +17,19 @@
 ?>
 --EXPECTF--
 bool(true)
-array(16) {
+array(17) {
   ["name"]=>
-  string(96) "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net"
+  string(96) "/CN=Henrique do N. Angelo/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/emailAddress=hnangelo@php.net"
   ["subject"]=>
   array(5) {
+    ["CN"]=>
+    string(21) "Henrique do N. Angelo"
     ["C"]=>
     string(2) "BR"
     ["ST"]=>
     string(17) "Rio Grande do Sul"
     ["L"]=>
     string(12) "Porto Alegre"
-    ["CN"]=>
-    string(21) "Henrique do N. Angelo"
     ["emailAddress"]=>
     string(16) "hnangelo@php.net"
   }
@@ -37,31 +37,31 @@
   string(8) "%s"
   ["issuer"]=>
   array(5) {
+    ["CN"]=>
+    string(21) "Henrique do N. Angelo"
     ["C"]=>
     string(2) "BR"
     ["ST"]=>
     string(17) "Rio Grande do Sul"
     ["L"]=>
     string(12) "Porto Alegre"
-    ["CN"]=>
-    string(21) "Henrique do N. Angelo"
     ["emailAddress"]=>
     string(16) "hnangelo@php.net"
   }
   ["version"]=>
   int(2)
   ["serialNumber"]=>
-  string(20) "12593567369101004962"
+  string(42) "0x5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198"
   ["serialNumberHex"]=>
-  string(16) "AEC556CC723750A2"
+  string(40) "5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198"
   ["validFrom"]=>
-  string(13) "080630102843Z"
+  string(13) "251002180630Z"
   ["validTo"]=>
-  string(13) "080730102843Z"
+  string(13) "261002180630Z"
   ["validFrom_time_t"]=>
-  int(1214821723)
+  int(1759428390)
   ["validTo_time_t"]=>
-  int(1217413723)
+  int(1790964390)
   ["signatureTypeSN"]=>
   string(8) "RSA-SHA1"
   ["signatureTypeLN"]=>
@@ -157,26 +157,29 @@
     ["subjectKeyIdentifier"]=>
     string(59) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D"
     ["authorityKeyIdentifier"]=>
-    string(%d) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D
-DirName:/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net
-serial:AE:C5:56:CC:72:37:50:A2%A"
+    string(%d) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D"
     ["basicConstraints"]=>
     string(7) "CA:TRUE"
   }
+  ["criticalExtensions"]=>
+  array(1) {
+    [0]=>
+    string(16) "basicConstraints"
+  }
 }
-array(16) {
+array(17) {
   ["name"]=>
-  string(96) "/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net"
+  string(96) "/CN=Henrique do N. Angelo/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/emailAddress=hnangelo@php.net"
   ["subject"]=>
   array(5) {
+    ["commonName"]=>
+    string(21) "Henrique do N. Angelo"
     ["countryName"]=>
     string(2) "BR"
     ["stateOrProvinceName"]=>
     string(17) "Rio Grande do Sul"
     ["localityName"]=>
     string(12) "Porto Alegre"
-    ["commonName"]=>
-    string(21) "Henrique do N. Angelo"
     ["emailAddress"]=>
     string(16) "hnangelo@php.net"
   }
@@ -184,31 +187,31 @@
   string(8) "%s"
   ["issuer"]=>
   array(5) {
+    ["commonName"]=>
+    string(21) "Henrique do N. Angelo"
     ["countryName"]=>
     string(2) "BR"
     ["stateOrProvinceName"]=>
     string(17) "Rio Grande do Sul"
     ["localityName"]=>
     string(12) "Porto Alegre"
-    ["commonName"]=>
-    string(21) "Henrique do N. Angelo"
     ["emailAddress"]=>
     string(16) "hnangelo@php.net"
   }
   ["version"]=>
   int(2)
   ["serialNumber"]=>
-  string(20) "12593567369101004962"
+  string(42) "0x5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198"
   ["serialNumberHex"]=>
-  string(16) "AEC556CC723750A2"
+  string(40) "5EE94A5F3A71AF7DEC57FD8BC08D3ECA1A540198"
   ["validFrom"]=>
-  string(13) "080630102843Z"
+  string(13) "251002180630Z"
   ["validTo"]=>
-  string(13) "080730102843Z"
+  string(13) "261002180630Z"
   ["validFrom_time_t"]=>
-  int(1214821723)
+  int(1759428390)
   ["validTo_time_t"]=>
-  int(1217413723)
+  int(1790964390)
   ["signatureTypeSN"]=>
   string(8) "RSA-SHA1"
   ["signatureTypeLN"]=>
@@ -304,10 +307,13 @@
     ["subjectKeyIdentifier"]=>
     string(59) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D"
     ["authorityKeyIdentifier"]=>
-    string(%d) "keyid:DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D
-DirName:/C=BR/ST=Rio Grande do Sul/L=Porto Alegre/CN=Henrique do N. Angelo/emailAddress=hnangelo@php.net
-serial:AE:C5:56:CC:72:37:50:A2%A"
+    string(%d) "DB:7E:40:72:BD:5C:35:85:EC:29:29:81:12:E8:62:68:6A:B7:3F:7D"
     ["basicConstraints"]=>
     string(7) "CA:TRUE"
   }
+  ["criticalExtensions"]=>
+  array(1) {
+    [0]=>
+    string(16) "basicConstraints"
+  }
 }