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.clouddiff --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-2024 The PHP Group All rights reserved. |
Last updated: Thu Nov 21 12:01:29 2024 UTC |