Skip to content

Commit ac8d0e5

Browse files
committed
Prevent unexpected array entry conversion when reading key
When passing an array, the key entry can get converted to a string if it is an object, but this actually modifies the original array entry. The test originally outputted: ``` array(2) { [0]=> string(...) => ... [1]=> string(0) "" } ``` This is unexpected. Use zval_try_get_string() to prevent this behaviour. Closes phpGH-16693.
1 parent 065bde1 commit ac8d0e5

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ PHP NEWS
88
- FPM:
99
. Fixed GH-16432 (PHP-FPM 8.2 SIGSEGV in fpm_get_status). (Jakub Zelenka)
1010

11+
- OpenSSL:
12+
. Prevent unexpected array entry conversion when reading key. (nielsdos)
13+
1114
- PDO:
1215
. Fixed memory leak of `setFetchMode()`. (SakiTakamachi)
1316

ext/openssl/openssl.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3577,19 +3577,21 @@ static EVP_PKEY *php_openssl_pkey_from_zval(
35773577
if (!(Z_TYPE_P(val) == IS_STRING || Z_TYPE_P(val) == IS_OBJECT)) {
35783578
TMP_CLEAN;
35793579
}
3580-
if (!try_convert_to_string(val)) {
3580+
zend_string *val_str = zval_try_get_string(val);
3581+
if (!val_str) {
35813582
TMP_CLEAN;
35823583
}
35833584

3584-
if (Z_STRLEN_P(val) > 7 && memcmp(Z_STRVAL_P(val), "file://", sizeof("file://") - 1) == 0) {
3585-
if (!php_openssl_check_path_str(Z_STR_P(val), file_path, arg_num)) {
3585+
if (ZSTR_LEN(val_str) > 7 && memcmp(ZSTR_VAL(val_str), "file://", sizeof("file://") - 1) == 0) {
3586+
if (!php_openssl_check_path_str(val_str, file_path, arg_num)) {
3587+
zend_string_release_ex(val_str, false);
35863588
TMP_CLEAN;
35873589
}
35883590
is_file = true;
35893591
}
35903592
/* it's an X509 file/cert of some kind, and we need to extract the data from that */
35913593
if (public_key) {
3592-
cert = php_openssl_x509_from_str(Z_STR_P(val), arg_num, false, NULL);
3594+
cert = php_openssl_x509_from_str(val_str, arg_num, false, NULL);
35933595

35943596
if (cert) {
35953597
free_cert = 1;
@@ -3599,10 +3601,11 @@ static EVP_PKEY *php_openssl_pkey_from_zval(
35993601
if (is_file) {
36003602
in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
36013603
} else {
3602-
in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val));
3604+
in = BIO_new_mem_buf(ZSTR_VAL(val_str), (int)ZSTR_LEN(val_str));
36033605
}
36043606
if (in == NULL) {
36053607
php_openssl_store_errors();
3608+
zend_string_release_ex(val_str, false);
36063609
TMP_CLEAN;
36073610
}
36083611
key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);
@@ -3615,10 +3618,11 @@ static EVP_PKEY *php_openssl_pkey_from_zval(
36153618
if (is_file) {
36163619
in = BIO_new_file(file_path, PHP_OPENSSL_BIO_MODE_R(PKCS7_BINARY));
36173620
} else {
3618-
in = BIO_new_mem_buf(Z_STRVAL_P(val), (int)Z_STRLEN_P(val));
3621+
in = BIO_new_mem_buf(ZSTR_VAL(val_str), (int)ZSTR_LEN(val_str));
36193622
}
36203623

36213624
if (in == NULL) {
3625+
zend_string_release_ex(val_str, false);
36223626
TMP_CLEAN;
36233627
}
36243628
if (passphrase == NULL) {
@@ -3631,6 +3635,8 @@ static EVP_PKEY *php_openssl_pkey_from_zval(
36313635
}
36323636
BIO_free(in);
36333637
}
3638+
3639+
zend_string_release_ex(val_str, false);
36343640
}
36353641

36363642
if (key == NULL) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
openssl_pkey_export_to_file object to string conversion
3+
--EXTENSIONS--
4+
openssl
5+
--FILE--
6+
<?php
7+
8+
class Test {
9+
public function __toString(): string {
10+
return "file://" . __DIR__ . "/private_rsa_1024.key";
11+
}
12+
}
13+
14+
$path = new Test;
15+
$key = [$path, ""];
16+
@openssl_pkey_export_to_file($key, str_repeat("a", 10000), passphrase: "");
17+
var_dump($key);
18+
19+
?>
20+
--EXPECT--
21+
array(2) {
22+
[0]=>
23+
object(Test)#1 (0) {
24+
}
25+
[1]=>
26+
string(0) ""
27+
}

0 commit comments

Comments
 (0)