|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patch fix_php_openssl_cms_pkcs7_encrypt for OpenSSL related Bug #81724Patch version 2022-07-05 15:25 UTC Return to Bug #81724 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: johannes.drummer@power.cloud
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index dd9a891ed8..4ad44ac109 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -5411,6 +5411,36 @@ PHP_FUNCTION(openssl_pkcs7_verify)
}
/* }}} */
+/** Helper to allow backwards compatibility for functions previously using CONSTANTS */
+const EVP_CIPHER* php_openssl_get_evp_cipher_from_string_or_id(zval * cipher_zval)
+{
+ char * cipher_algo_str = NULL;
+ size_t cipher_algo_str_len = 0;
+ const EVP_CIPHER* cipher = 0;
+ zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
+
+ if (Z_TYPE_P(cipher_zval) == IS_STRING) {
+ cipher_algo_str = Z_STRVAL_P(cipher_zval);
+ cipher_algo_str_len = Z_STRLEN_P(cipher_zval);
+ PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(cipher_algo_str_len, cipher_algo_str);
+ cipher = EVP_get_cipherbyname(cipher_algo_str);
+ if (!cipher) {
+ return NULL;
+ }
+ } else {
+ if (Z_TYPE_P(cipher_zval) == IS_LONG) {
+ cipherid = Z_LVAL_P(cipher_zval);
+ }
+ /* sanity check the cipher */
+ cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
+ if (cipher == NULL) {
+ return NULL;
+ }
+ }
+
+ return cipher;
+}
+
/* {{{ Encrypts the message in the file named infile with the certificates in recipcerts and output the result to the file named outfile */
PHP_FUNCTION(openssl_pkcs7_encrypt)
{
@@ -5422,7 +5452,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
zval * zcertval;
X509 * cert;
const EVP_CIPHER *cipher = NULL;
- zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
+ zval * cipher_algo;
zend_string * strindex;
char * infilename = NULL;
size_t infilename_len;
@@ -5431,8 +5461,8 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|ll", &infilename, &infilename_len,
- &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|lz", &infilename, &infilename_len,
+ &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipher_algo) == FAILURE) {
RETURN_THROWS();
}
@@ -5492,10 +5522,8 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
sk_X509_push(recipcerts, cert);
}
- /* sanity check the cipher */
- cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
+ cipher = php_openssl_get_evp_cipher_from_string_or_id(cipher_algo);
if (cipher == NULL) {
- /* shouldn't happen */
php_error_docref(NULL, E_WARNING, "Failed to get cipher");
goto clean_exit;
}
@@ -6018,7 +6046,7 @@ PHP_FUNCTION(openssl_cms_encrypt)
zval * zcertval;
X509 * cert;
const EVP_CIPHER *cipher = NULL;
- zend_long cipherid = PHP_OPENSSL_CIPHER_DEFAULT;
+ zval * cipher_algo = NULL;
zend_string * strindex;
char * infilename = NULL;
size_t infilename_len;
@@ -6028,8 +6056,8 @@ PHP_FUNCTION(openssl_cms_encrypt)
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|lll", &infilename, &infilename_len,
- &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &encoding, &cipherid) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ppza!|llz", &infilename, &infilename_len,
+ &outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &encoding, &cipher_algo) == FAILURE) {
RETURN_THROWS();
}
@@ -6090,10 +6118,8 @@ PHP_FUNCTION(openssl_cms_encrypt)
sk_X509_push(recipcerts, cert);
}
- /* sanity check the cipher */
- cipher = php_openssl_get_evp_cipher_from_algo(cipherid);
+ cipher = php_openssl_get_evp_cipher_from_string_or_id(cipher_algo);
if (cipher == NULL) {
- /* shouldn't happen */
php_error_docref(NULL, E_WARNING, "Failed to get cipher");
goto clean_exit;
}
diff --git a/ext/openssl/tests/openssl_cms_decrypt_basic_algo.phpt b/ext/openssl/tests/openssl_cms_decrypt_basic_algo.phpt
new file mode 100644
index 0000000000..0db30e92c7
--- /dev/null
+++ b/ext/openssl/tests/openssl_cms_decrypt_basic_algo.phpt
@@ -0,0 +1,69 @@
+--TEST--
+openssl_cms_decrypt() tests
+--EXTENSIONS--
+openssl
+--FILE--
+<?php
+$infile = __DIR__ . "/plain.txt";
+$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
+$encrypted = tempnam(sys_get_temp_dir(), "cms_dec_basic");
+if ($encrypted === false)
+ die("failed to get a temporary filename!");
+$outfile = $encrypted . ".out";
+
+$single_cert = "file://" . __DIR__ . "/cert.crt";
+$headers = array("test@test", "testing openssl_cms_encrypt()");
+$wrong = "wrong";
+$empty = "";
+$cipher = "aes-256-gcm";
+
+openssl_cms_encrypt($infile, $encrypted, $single_cert, $headers, cipher_algo: $cipher);
+
+var_dump(openssl_cms_decrypt($encrypted, $outfile, $single_cert, $privkey));
+print("\nDecrypted text:\n");
+readfile($outfile);
+var_dump(openssl_cms_decrypt($encrypted, $outfile, openssl_x509_read($single_cert), $privkey));
+var_dump(openssl_cms_decrypt($encrypted, $outfile, $single_cert, $wrong));
+var_dump(openssl_cms_decrypt($encrypted, $outfile, $wrong, $privkey));
+var_dump(openssl_cms_decrypt($encrypted, $outfile, null, $privkey));
+var_dump(openssl_cms_decrypt($wrong, $outfile, $single_cert, $privkey));
+var_dump(openssl_cms_decrypt($empty, $outfile, $single_cert, $privkey));
+var_dump(openssl_cms_decrypt($encrypted, $empty, $single_cert, $privkey));
+var_dump(openssl_cms_decrypt($encrypted, $outfile, $empty, $privkey));
+var_dump(openssl_cms_decrypt($encrypted, $outfile, $single_cert, $empty));
+
+if (file_exists($encrypted)) {
+ echo "true\n";
+ unlink($encrypted);
+}
+if (file_exists($outfile)) {
+ echo "true\n";
+ unlink($outfile);
+}
+?>
+--EXPECTF--
+bool(true)
+
+Decrypted text:
+Now is the winter of our discontent.
+bool(true)
+
+Warning: openssl_cms_decrypt(): Unable to get private key in %s on line %d
+bool(false)
+
+Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d
+bool(false)
+
+Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+
+Warning: openssl_cms_decrypt(): X.509 Certificate cannot be retrieved in %s on line %d
+bool(false)
+
+Warning: openssl_cms_decrypt(): Unable to get private key in %s on line %d
+bool(false)
+true
+true
diff --git a/ext/openssl/tests/openssl_cms_encrypt_basic_algo.phpt b/ext/openssl/tests/openssl_cms_encrypt_basic_algo.phpt
new file mode 100644
index 0000000000..b0e8732b73
--- /dev/null
+++ b/ext/openssl/tests/openssl_cms_encrypt_basic_algo.phpt
@@ -0,0 +1,61 @@
+--TEST--
+openssl_cms_encrypt() tests
+--EXTENSIONS--
+openssl
+--FILE--
+<?php
+$infile = __DIR__ . "/plain.txt";
+$outfile = tempnam(sys_get_temp_dir(), "cms_enc_basic");
+if ($outfile === false)
+ die("failed to get a temporary filename!");
+$outfile2 = $outfile . ".out";
+$single_cert = "file://" . __DIR__ . "/cert.crt";
+$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
+$wrongkey = "file://" . __DIR__ . "/private_rsa_2048.key";
+$multi_certs = array($single_cert, $single_cert);
+$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_cms_encrypt()");
+$headers = array("test@test", "testing openssl_cms_encrypt()");
+$empty_headers = array();
+$wrong = "wrong";
+$empty = "";
+$cipher = "aes-256-gcm";
+
+var_dump(openssl_cms_encrypt($infile, $outfile, $single_cert, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $outfile, openssl_x509_read($single_cert), $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_decrypt($outfile, $outfile2, $single_cert, $privkey));
+readfile($outfile2);
+var_dump(openssl_cms_encrypt($infile, $outfile, $single_cert, $assoc_headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $outfile, $single_cert, $empty_headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($wrong, $outfile, $single_cert, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($empty, $outfile, $single_cert, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $empty, $single_cert, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $outfile, $wrong, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $outfile, $empty, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $outfile, $multi_certs, $headers, cipher_algo: $cipher));
+var_dump(openssl_cms_encrypt($infile, $outfile, array_map('openssl_x509_read', $multi_certs), $headers, cipher_algo: $cipher));
+
+if (file_exists($outfile)) {
+ echo "true\n";
+ unlink($outfile);
+}
+if (file_exists($outfile2)) {
+ echo "true\n";
+ unlink($outfile2);
+}
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+Now is the winter of our discontent.
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+true
+true
|
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Dec 06 10:00:01 2025 UTC |