diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index aab240dc8506a..f898f0eee98e6 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4323,7 +4323,7 @@ PHP_FUNCTION(openssl_digest) if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &data, &data_len, &method, &method_len, &raw_output) == FAILURE) { RETURN_THROWS(); } - mdtype = EVP_get_digestbyname(method); + mdtype = php_openssl_get_evp_md_by_name(method); if (!mdtype) { php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); RETURN_FALSE; diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 0cda27407a567..bbb4c19e56ae7 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -469,92 +469,6 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se return SUCCESS; } -EVP_MD * php_openssl_get_evp_md_from_algo(zend_long algo) { - EVP_MD *mdtype; - - switch (algo) { - case OPENSSL_ALGO_SHA1: - mdtype = (EVP_MD *) EVP_sha1(); - break; - case OPENSSL_ALGO_MD5: - mdtype = (EVP_MD *) EVP_md5(); - break; -#ifndef OPENSSL_NO_MD4 - case OPENSSL_ALGO_MD4: - mdtype = (EVP_MD *) EVP_md4(); - break; -#endif -#ifndef OPENSSL_NO_MD2 - case OPENSSL_ALGO_MD2: - mdtype = (EVP_MD *) EVP_md2(); - break; -#endif - case OPENSSL_ALGO_SHA224: - mdtype = (EVP_MD *) EVP_sha224(); - break; - case OPENSSL_ALGO_SHA256: - mdtype = (EVP_MD *) EVP_sha256(); - break; - case OPENSSL_ALGO_SHA384: - mdtype = (EVP_MD *) EVP_sha384(); - break; - case OPENSSL_ALGO_SHA512: - mdtype = (EVP_MD *) EVP_sha512(); - break; -#ifndef OPENSSL_NO_RMD160 - case OPENSSL_ALGO_RMD160: - mdtype = (EVP_MD *) EVP_ripemd160(); - break; -#endif - default: - return NULL; - break; - } - return mdtype; -} - -const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo) { - switch (algo) { -#ifndef OPENSSL_NO_RC2 - case PHP_OPENSSL_CIPHER_RC2_40: - return EVP_rc2_40_cbc(); - break; - case PHP_OPENSSL_CIPHER_RC2_64: - return EVP_rc2_64_cbc(); - break; - case PHP_OPENSSL_CIPHER_RC2_128: - return EVP_rc2_cbc(); - break; -#endif - -#ifndef OPENSSL_NO_DES - case PHP_OPENSSL_CIPHER_DES: - return EVP_des_cbc(); - break; - case PHP_OPENSSL_CIPHER_3DES: - return EVP_des_ede3_cbc(); - break; -#endif - -#ifndef OPENSSL_NO_AES - case PHP_OPENSSL_CIPHER_AES_128_CBC: - return EVP_aes_128_cbc(); - break; - case PHP_OPENSSL_CIPHER_AES_192_CBC: - return EVP_aes_192_cbc(); - break; - case PHP_OPENSSL_CIPHER_AES_256_CBC: - return EVP_aes_256_cbc(); - break; -#endif - - - default: - return NULL; - break; - } -} - void php_openssl_backend_init(void) { #ifdef LIBRESSL_VERSION_NUMBER @@ -1931,7 +1845,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt( PHP_OPENSSL_CHECK_LONG_TO_INT_NULL_RETURN(tag_len, tag_len); - cipher_type = EVP_get_cipherbyname(method); + cipher_type = php_openssl_get_evp_cipher_by_name(method); if (!cipher_type) { php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); return NULL; @@ -2023,7 +1937,7 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt( PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(tag_len, tag); - cipher_type = EVP_get_cipherbyname(method); + cipher_type = php_openssl_get_evp_cipher_by_name(method); if (!cipher_type) { php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); return NULL; @@ -2079,11 +1993,11 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt( return outbuf; } -const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method) +const EVP_CIPHER *php_openssl_get_evp_cipher_by_name_with_warning(const char *method) { const EVP_CIPHER *cipher_type; - cipher_type = EVP_get_cipherbyname(method); + cipher_type = php_openssl_get_evp_cipher_by_name(method); if (!cipher_type) { php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); return NULL; @@ -2095,14 +2009,14 @@ const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method) PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method) { - const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method); + const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name_with_warning(method); return cipher_type == NULL ? -1 : EVP_CIPHER_iv_length(cipher_type); } PHP_OPENSSL_API zend_long php_openssl_cipher_key_length(const char *method) { - const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method); + const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name_with_warning(method); return cipher_type == NULL ? -1 : EVP_CIPHER_key_length(cipher_type); } diff --git a/ext/openssl/openssl_backend_v1.c b/ext/openssl/openssl_backend_v1.c index eb94ee3fbe4bc..bbb7ba58e5317 100644 --- a/ext/openssl/openssl_backend_v1.c +++ b/ext/openssl/openssl_backend_v1.c @@ -561,6 +561,104 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu return data; } +const EVP_MD *php_openssl_get_evp_md_by_name(const char *name) +{ + return EVP_get_digestbyname(name); +} + +const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo) +{ + EVP_MD *mdtype; + + switch (algo) { + case OPENSSL_ALGO_SHA1: + mdtype = (EVP_MD *) EVP_sha1(); + break; + case OPENSSL_ALGO_MD5: + mdtype = (EVP_MD *) EVP_md5(); + break; +#ifndef OPENSSL_NO_MD4 + case OPENSSL_ALGO_MD4: + mdtype = (EVP_MD *) EVP_md4(); + break; +#endif +#ifndef OPENSSL_NO_MD2 + case OPENSSL_ALGO_MD2: + mdtype = (EVP_MD *) EVP_md2(); + break; +#endif + case OPENSSL_ALGO_SHA224: + mdtype = (EVP_MD *) EVP_sha224(); + break; + case OPENSSL_ALGO_SHA256: + mdtype = (EVP_MD *) EVP_sha256(); + break; + case OPENSSL_ALGO_SHA384: + mdtype = (EVP_MD *) EVP_sha384(); + break; + case OPENSSL_ALGO_SHA512: + mdtype = (EVP_MD *) EVP_sha512(); + break; +#ifndef OPENSSL_NO_RMD160 + case OPENSSL_ALGO_RMD160: + mdtype = (EVP_MD *) EVP_ripemd160(); + break; +#endif + default: + return NULL; + break; + } + return mdtype; +} + +const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name) +{ + return EVP_get_cipherbyname(name); +} + +const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo) +{ + switch (algo) { +#ifndef OPENSSL_NO_RC2 + case PHP_OPENSSL_CIPHER_RC2_40: + return EVP_rc2_40_cbc(); + break; + case PHP_OPENSSL_CIPHER_RC2_64: + return EVP_rc2_64_cbc(); + break; + case PHP_OPENSSL_CIPHER_RC2_128: + return EVP_rc2_cbc(); + break; +#endif + +#ifndef OPENSSL_NO_DES + case PHP_OPENSSL_CIPHER_DES: + return EVP_des_cbc(); + break; + case PHP_OPENSSL_CIPHER_3DES: + return EVP_des_ede3_cbc(); + break; +#endif + +#ifndef OPENSSL_NO_AES + case PHP_OPENSSL_CIPHER_AES_128_CBC: + return EVP_aes_128_cbc(); + break; + case PHP_OPENSSL_CIPHER_AES_192_CBC: + return EVP_aes_192_cbc(); + break; + case PHP_OPENSSL_CIPHER_AES_256_CBC: + return EVP_aes_256_cbc(); + break; +#endif + + + default: + return NULL; + break; + } +} + void php_openssl_get_cipher_methods(zval *return_value, bool aliases) { array_init(return_value); diff --git a/ext/openssl/openssl_backend_v3.c b/ext/openssl/openssl_backend_v3.c index 0876690aee0ba..e0eba9ddf1e23 100644 --- a/ext/openssl/openssl_backend_v3.c +++ b/ext/openssl/openssl_backend_v3.c @@ -696,6 +696,73 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu return result; } +const EVP_MD *php_openssl_get_evp_md_by_name(const char *name) +{ + return EVP_MD_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq)); +} + +static const char *php_openssl_digest_names[] = { + [OPENSSL_ALGO_SHA1] = "SHA1", + [OPENSSL_ALGO_MD5] = "MD5", +#ifndef OPENSSL_NO_MD4 + [OPENSSL_ALGO_MD4] = "MD4", +#endif +#ifndef OPENSSL_NO_MD2 + [OPENSSL_ALGO_MD2] = "MD2", +#endif + [OPENSSL_ALGO_SHA224] = "SHA224", + [OPENSSL_ALGO_SHA256] = "SHA256", + [OPENSSL_ALGO_SHA384] = "SHA384", + [OPENSSL_ALGO_SHA512] = "SHA512", +#ifndef OPENSSL_NO_RMD160 + [OPENSSL_ALGO_RMD160] = "RIPEMD160", +#endif +}; + +const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo) +{ + if (algo < 0 || algo >= (zend_long)(sizeof(php_openssl_digest_names) / sizeof(*php_openssl_digest_names))) { + return NULL; + } + + const char *name = php_openssl_digest_names[algo]; + if (!name) { + return NULL; + } + + return php_openssl_get_evp_md_by_name(name); +} + +static const char *php_openssl_cipher_names[] = { + [PHP_OPENSSL_CIPHER_RC2_40] = "RC2-40-CBC", + [PHP_OPENSSL_CIPHER_RC2_128] = "RC2-CBC", + [PHP_OPENSSL_CIPHER_RC2_64] = "RC2-64-CBC", + [PHP_OPENSSL_CIPHER_DES] = "DES-CBC", + [PHP_OPENSSL_CIPHER_3DES] = "DES-EDE3-CBC", + [PHP_OPENSSL_CIPHER_AES_128_CBC]= "AES-128-CBC", + [PHP_OPENSSL_CIPHER_AES_192_CBC]= "AES-192-CBC", + [PHP_OPENSSL_CIPHER_AES_256_CBC]= "AES-256-CBC", +}; + +const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name) +{ + return EVP_CIPHER_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq)); +} + +const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo) +{ + if (algo < 0 || algo >= (zend_long)(sizeof(php_openssl_cipher_names) / sizeof(*php_openssl_cipher_names))) { + return NULL; + } + + const char *name = php_openssl_cipher_names[algo]; + if (!name) { + return NULL; + } + + return php_openssl_get_evp_cipher_by_name(name); +} + static void php_openssl_add_cipher_name(const char *name, void *arg) { size_t len = strlen(name); @@ -722,7 +789,7 @@ static int php_openssl_compare_func(Bucket *a, Bucket *b) void php_openssl_get_cipher_methods(zval *return_value, bool aliases) { array_init(return_value); - EVP_CIPHER_do_all_provided(NULL, + EVP_CIPHER_do_all_provided(OPENSSL_G(libctx), aliases ? php_openssl_add_cipher_or_alias : php_openssl_add_cipher, return_value); zend_hash_sort(Z_ARRVAL_P(return_value), php_openssl_compare_func, 1); diff --git a/ext/openssl/php_openssl_backend.h b/ext/openssl/php_openssl_backend.h index 5cfa73160b853..0142011710d80 100644 --- a/ext/openssl/php_openssl_backend.h +++ b/ext/openssl/php_openssl_backend.h @@ -75,14 +75,17 @@ enum php_openssl_key_type { OPENSSL_KEYTYPE_RSA, OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH, + OPENSSL_KEYTYPE_EC, + OPENSSL_KEYTYPE_X25519, + OPENSSL_KEYTYPE_ED25519, + OPENSSL_KEYTYPE_X448, + OPENSSL_KEYTYPE_ED448, + OPENSSL_KEYTYPE_DEFAULT = OPENSSL_KEYTYPE_RSA, - OPENSSL_KEYTYPE_EC = OPENSSL_KEYTYPE_DH +1, - OPENSSL_KEYTYPE_X25519 = OPENSSL_KEYTYPE_DH +2, - OPENSSL_KEYTYPE_ED25519 = OPENSSL_KEYTYPE_DH +3, - OPENSSL_KEYTYPE_X448 = OPENSSL_KEYTYPE_DH +4, - OPENSSL_KEYTYPE_ED448 = OPENSSL_KEYTYPE_DH +5, }; +/* Cipher constants, do not forget to update php_openssl_cipher_names in + * openssl_backend_v3.c if new constant added. */ enum php_openssl_cipher_type { PHP_OPENSSL_CIPHER_RC2_40, PHP_OPENSSL_CIPHER_RC2_128, @@ -106,10 +109,10 @@ enum php_openssl_encoding { ENCODING_PEM, }; - #define MIN_KEY_LENGTH 384 -/* constants used in ext/phar/util.c, keep in sync */ +/* Constants used in ext/phar/util.c, keep in sync and do not forget to update + * php_openssl_digest_names in openssl_backend_v3.c if new constant added. */ #define OPENSSL_ALGO_SHA1 1 #define OPENSSL_ALGO_MD5 2 #ifndef OPENSSL_NO_MD4 @@ -126,6 +129,7 @@ enum php_openssl_encoding { #ifndef OPENSSL_NO_RMD160 #define OPENSSL_ALGO_RMD160 10 #endif + #define DEBUG_SMIME 0 #if !defined(OPENSSL_NO_EC) && defined(EVP_PKEY_EC) @@ -221,7 +225,9 @@ void php_openssl_dispose_config(struct php_x509_request * req); zend_result php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded); zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int seeded); -EVP_MD * php_openssl_get_evp_md_from_algo(zend_long algo); +const EVP_MD *php_openssl_get_evp_md_by_name(const char *name); +const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo); +const EVP_CIPHER * php_openssl_get_evp_cipher_by_name(const char *name); const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo); void php_openssl_backend_init(void);