Skip to content

Commit e8e295b

Browse files
committed
Use custom OpenSSL libctx in md and cipher handling code
1 parent cb4bafa commit e8e295b

File tree

5 files changed

+187
-102
lines changed

5 files changed

+187
-102
lines changed

ext/openssl/openssl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4323,7 +4323,7 @@ PHP_FUNCTION(openssl_digest)
43234323
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &data, &data_len, &method, &method_len, &raw_output) == FAILURE) {
43244324
RETURN_THROWS();
43254325
}
4326-
mdtype = EVP_get_digestbyname(method);
4326+
mdtype = php_openssl_get_evp_md_by_name(method);
43274327
if (!mdtype) {
43284328
php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
43294329
RETURN_FALSE;

ext/openssl/openssl_backend_common.c

Lines changed: 6 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -469,92 +469,6 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se
469469
return SUCCESS;
470470
}
471471

472-
EVP_MD * php_openssl_get_evp_md_from_algo(zend_long algo) {
473-
EVP_MD *mdtype;
474-
475-
switch (algo) {
476-
case OPENSSL_ALGO_SHA1:
477-
mdtype = (EVP_MD *) EVP_sha1();
478-
break;
479-
case OPENSSL_ALGO_MD5:
480-
mdtype = (EVP_MD *) EVP_md5();
481-
break;
482-
#ifndef OPENSSL_NO_MD4
483-
case OPENSSL_ALGO_MD4:
484-
mdtype = (EVP_MD *) EVP_md4();
485-
break;
486-
#endif
487-
#ifndef OPENSSL_NO_MD2
488-
case OPENSSL_ALGO_MD2:
489-
mdtype = (EVP_MD *) EVP_md2();
490-
break;
491-
#endif
492-
case OPENSSL_ALGO_SHA224:
493-
mdtype = (EVP_MD *) EVP_sha224();
494-
break;
495-
case OPENSSL_ALGO_SHA256:
496-
mdtype = (EVP_MD *) EVP_sha256();
497-
break;
498-
case OPENSSL_ALGO_SHA384:
499-
mdtype = (EVP_MD *) EVP_sha384();
500-
break;
501-
case OPENSSL_ALGO_SHA512:
502-
mdtype = (EVP_MD *) EVP_sha512();
503-
break;
504-
#ifndef OPENSSL_NO_RMD160
505-
case OPENSSL_ALGO_RMD160:
506-
mdtype = (EVP_MD *) EVP_ripemd160();
507-
break;
508-
#endif
509-
default:
510-
return NULL;
511-
break;
512-
}
513-
return mdtype;
514-
}
515-
516-
const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo) {
517-
switch (algo) {
518-
#ifndef OPENSSL_NO_RC2
519-
case PHP_OPENSSL_CIPHER_RC2_40:
520-
return EVP_rc2_40_cbc();
521-
break;
522-
case PHP_OPENSSL_CIPHER_RC2_64:
523-
return EVP_rc2_64_cbc();
524-
break;
525-
case PHP_OPENSSL_CIPHER_RC2_128:
526-
return EVP_rc2_cbc();
527-
break;
528-
#endif
529-
530-
#ifndef OPENSSL_NO_DES
531-
case PHP_OPENSSL_CIPHER_DES:
532-
return EVP_des_cbc();
533-
break;
534-
case PHP_OPENSSL_CIPHER_3DES:
535-
return EVP_des_ede3_cbc();
536-
break;
537-
#endif
538-
539-
#ifndef OPENSSL_NO_AES
540-
case PHP_OPENSSL_CIPHER_AES_128_CBC:
541-
return EVP_aes_128_cbc();
542-
break;
543-
case PHP_OPENSSL_CIPHER_AES_192_CBC:
544-
return EVP_aes_192_cbc();
545-
break;
546-
case PHP_OPENSSL_CIPHER_AES_256_CBC:
547-
return EVP_aes_256_cbc();
548-
break;
549-
#endif
550-
551-
552-
default:
553-
return NULL;
554-
break;
555-
}
556-
}
557-
558472
void php_openssl_backend_init(void)
559473
{
560474
#ifdef LIBRESSL_VERSION_NUMBER
@@ -1931,7 +1845,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt(
19311845
PHP_OPENSSL_CHECK_LONG_TO_INT_NULL_RETURN(tag_len, tag_len);
19321846

19331847

1934-
cipher_type = EVP_get_cipherbyname(method);
1848+
cipher_type = php_openssl_get_evp_cipher_by_name(method);
19351849
if (!cipher_type) {
19361850
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
19371851
return NULL;
@@ -2023,7 +1937,7 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt(
20231937
PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(tag_len, tag);
20241938

20251939

2026-
cipher_type = EVP_get_cipherbyname(method);
1940+
cipher_type = php_openssl_get_evp_cipher_by_name(method);
20271941
if (!cipher_type) {
20281942
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
20291943
return NULL;
@@ -2079,11 +1993,11 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt(
20791993
return outbuf;
20801994
}
20811995

2082-
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method)
1996+
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name_with_warning(const char *method)
20831997
{
20841998
const EVP_CIPHER *cipher_type;
20851999

2086-
cipher_type = EVP_get_cipherbyname(method);
2000+
cipher_type = php_openssl_get_evp_cipher_by_name(method);
20872001
if (!cipher_type) {
20882002
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
20892003
return NULL;
@@ -2095,14 +2009,14 @@ const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method)
20952009

20962010
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method)
20972011
{
2098-
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
2012+
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name_with_warning(method);
20992013

21002014
return cipher_type == NULL ? -1 : EVP_CIPHER_iv_length(cipher_type);
21012015
}
21022016

21032017
PHP_OPENSSL_API zend_long php_openssl_cipher_key_length(const char *method)
21042018
{
2105-
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
2019+
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name_with_warning(method);
21062020

21072021
return cipher_type == NULL ? -1 : EVP_CIPHER_key_length(cipher_type);
21082022
}

ext/openssl/openssl_backend_v1.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,104 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu
561561
return data;
562562
}
563563

564+
const EVP_MD *php_openssl_get_evp_md_by_name(const char *name)
565+
{
566+
return EVP_get_digestbyname(name);
567+
}
568+
569+
const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo)
570+
{
571+
EVP_MD *mdtype;
572+
573+
switch (algo) {
574+
case OPENSSL_ALGO_SHA1:
575+
mdtype = (EVP_MD *) EVP_sha1();
576+
break;
577+
case OPENSSL_ALGO_MD5:
578+
mdtype = (EVP_MD *) EVP_md5();
579+
break;
580+
#ifndef OPENSSL_NO_MD4
581+
case OPENSSL_ALGO_MD4:
582+
mdtype = (EVP_MD *) EVP_md4();
583+
break;
584+
#endif
585+
#ifndef OPENSSL_NO_MD2
586+
case OPENSSL_ALGO_MD2:
587+
mdtype = (EVP_MD *) EVP_md2();
588+
break;
589+
#endif
590+
case OPENSSL_ALGO_SHA224:
591+
mdtype = (EVP_MD *) EVP_sha224();
592+
break;
593+
case OPENSSL_ALGO_SHA256:
594+
mdtype = (EVP_MD *) EVP_sha256();
595+
break;
596+
case OPENSSL_ALGO_SHA384:
597+
mdtype = (EVP_MD *) EVP_sha384();
598+
break;
599+
case OPENSSL_ALGO_SHA512:
600+
mdtype = (EVP_MD *) EVP_sha512();
601+
break;
602+
#ifndef OPENSSL_NO_RMD160
603+
case OPENSSL_ALGO_RMD160:
604+
mdtype = (EVP_MD *) EVP_ripemd160();
605+
break;
606+
#endif
607+
default:
608+
return NULL;
609+
break;
610+
}
611+
return mdtype;
612+
}
613+
614+
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name)
615+
{
616+
return EVP_get_cipherbyname(name);
617+
}
618+
619+
const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo)
620+
{
621+
switch (algo) {
622+
#ifndef OPENSSL_NO_RC2
623+
case PHP_OPENSSL_CIPHER_RC2_40:
624+
return EVP_rc2_40_cbc();
625+
break;
626+
case PHP_OPENSSL_CIPHER_RC2_64:
627+
return EVP_rc2_64_cbc();
628+
break;
629+
case PHP_OPENSSL_CIPHER_RC2_128:
630+
return EVP_rc2_cbc();
631+
break;
632+
#endif
633+
634+
#ifndef OPENSSL_NO_DES
635+
case PHP_OPENSSL_CIPHER_DES:
636+
return EVP_des_cbc();
637+
break;
638+
case PHP_OPENSSL_CIPHER_3DES:
639+
return EVP_des_ede3_cbc();
640+
break;
641+
#endif
642+
643+
#ifndef OPENSSL_NO_AES
644+
case PHP_OPENSSL_CIPHER_AES_128_CBC:
645+
return EVP_aes_128_cbc();
646+
break;
647+
case PHP_OPENSSL_CIPHER_AES_192_CBC:
648+
return EVP_aes_192_cbc();
649+
break;
650+
case PHP_OPENSSL_CIPHER_AES_256_CBC:
651+
return EVP_aes_256_cbc();
652+
break;
653+
#endif
654+
655+
656+
default:
657+
return NULL;
658+
break;
659+
}
660+
}
661+
564662
void php_openssl_get_cipher_methods(zval *return_value, bool aliases)
565663
{
566664
array_init(return_value);

ext/openssl/openssl_backend_v3.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,73 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu
696696
return result;
697697
}
698698

699+
const EVP_MD *php_openssl_get_evp_md_by_name(const char *name)
700+
{
701+
return EVP_MD_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq));
702+
}
703+
704+
static const char *php_openssl_digest_names[] = {
705+
[OPENSSL_ALGO_SHA1] = "SHA1",
706+
[OPENSSL_ALGO_MD5] = "MD5",
707+
#ifndef OPENSSL_NO_MD4
708+
[OPENSSL_ALGO_MD4] = "MD4",
709+
#endif
710+
#ifndef OPENSSL_NO_MD2
711+
[OPENSSL_ALGO_MD2] = "MD2",
712+
#endif
713+
[OPENSSL_ALGO_SHA224] = "SHA224",
714+
[OPENSSL_ALGO_SHA256] = "SHA256",
715+
[OPENSSL_ALGO_SHA384] = "SHA384",
716+
[OPENSSL_ALGO_SHA512] = "SHA512",
717+
#ifndef OPENSSL_NO_RMD160
718+
[OPENSSL_ALGO_RMD160] = "RIPEMD160",
719+
#endif
720+
};
721+
722+
const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo)
723+
{
724+
if (algo < 0 || algo >= (zend_long)(sizeof(php_openssl_digest_names) / sizeof(*php_openssl_digest_names))) {
725+
return NULL;
726+
}
727+
728+
const char *name = php_openssl_digest_names[algo];
729+
if (!name) {
730+
return NULL;
731+
}
732+
733+
return php_openssl_get_evp_md_by_name(name);
734+
}
735+
736+
static const char *php_openssl_cipher_names[] = {
737+
[PHP_OPENSSL_CIPHER_RC2_40] = "RC2-40-CBC",
738+
[PHP_OPENSSL_CIPHER_RC2_128] = "RC2-CBC",
739+
[PHP_OPENSSL_CIPHER_RC2_64] = "RC2-64-CBC",
740+
[PHP_OPENSSL_CIPHER_DES] = "DES-CBC",
741+
[PHP_OPENSSL_CIPHER_3DES] = "DES-EDE3-CBC",
742+
[PHP_OPENSSL_CIPHER_AES_128_CBC]= "AES-128-CBC",
743+
[PHP_OPENSSL_CIPHER_AES_192_CBC]= "AES-192-CBC",
744+
[PHP_OPENSSL_CIPHER_AES_256_CBC]= "AES-256-CBC",
745+
};
746+
747+
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name)
748+
{
749+
return EVP_CIPHER_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq));
750+
}
751+
752+
const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo)
753+
{
754+
if (algo < 0 || algo >= (zend_long)(sizeof(php_openssl_cipher_names) / sizeof(*php_openssl_cipher_names))) {
755+
return NULL;
756+
}
757+
758+
const char *name = php_openssl_cipher_names[algo];
759+
if (!name) {
760+
return NULL;
761+
}
762+
763+
return php_openssl_get_evp_cipher_by_name(name);
764+
}
765+
699766
static void php_openssl_add_cipher_name(const char *name, void *arg)
700767
{
701768
size_t len = strlen(name);
@@ -722,7 +789,7 @@ static int php_openssl_compare_func(Bucket *a, Bucket *b)
722789
void php_openssl_get_cipher_methods(zval *return_value, bool aliases)
723790
{
724791
array_init(return_value);
725-
EVP_CIPHER_do_all_provided(NULL,
792+
EVP_CIPHER_do_all_provided(OPENSSL_G(libctx),
726793
aliases ? php_openssl_add_cipher_or_alias : php_openssl_add_cipher,
727794
return_value);
728795
zend_hash_sort(Z_ARRVAL_P(return_value), php_openssl_compare_func, 1);

ext/openssl/php_openssl_backend.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,17 @@ enum php_openssl_key_type {
7575
OPENSSL_KEYTYPE_RSA,
7676
OPENSSL_KEYTYPE_DSA,
7777
OPENSSL_KEYTYPE_DH,
78+
OPENSSL_KEYTYPE_EC,
79+
OPENSSL_KEYTYPE_X25519,
80+
OPENSSL_KEYTYPE_ED25519,
81+
OPENSSL_KEYTYPE_X448,
82+
OPENSSL_KEYTYPE_ED448,
83+
7884
OPENSSL_KEYTYPE_DEFAULT = OPENSSL_KEYTYPE_RSA,
79-
OPENSSL_KEYTYPE_EC = OPENSSL_KEYTYPE_DH +1,
80-
OPENSSL_KEYTYPE_X25519 = OPENSSL_KEYTYPE_DH +2,
81-
OPENSSL_KEYTYPE_ED25519 = OPENSSL_KEYTYPE_DH +3,
82-
OPENSSL_KEYTYPE_X448 = OPENSSL_KEYTYPE_DH +4,
83-
OPENSSL_KEYTYPE_ED448 = OPENSSL_KEYTYPE_DH +5,
8485
};
8586

87+
/* Cipher constants, do not forget to update php_openssl_cipher_names in
88+
* openssl_backend_v3.c if new constant added. */
8689
enum php_openssl_cipher_type {
8790
PHP_OPENSSL_CIPHER_RC2_40,
8891
PHP_OPENSSL_CIPHER_RC2_128,
@@ -106,10 +109,10 @@ enum php_openssl_encoding {
106109
ENCODING_PEM,
107110
};
108111

109-
110112
#define MIN_KEY_LENGTH 384
111113

112-
/* constants used in ext/phar/util.c, keep in sync */
114+
/* Constants used in ext/phar/util.c, keep in sync and do not forget to update
115+
* php_openssl_digest_names in openssl_backend_v3.c if new constant added. */
113116
#define OPENSSL_ALGO_SHA1 1
114117
#define OPENSSL_ALGO_MD5 2
115118
#ifndef OPENSSL_NO_MD4
@@ -126,6 +129,7 @@ enum php_openssl_encoding {
126129
#ifndef OPENSSL_NO_RMD160
127130
#define OPENSSL_ALGO_RMD160 10
128131
#endif
132+
129133
#define DEBUG_SMIME 0
130134

131135
#if !defined(OPENSSL_NO_EC) && defined(EVP_PKEY_EC)
@@ -221,7 +225,9 @@ void php_openssl_dispose_config(struct php_x509_request * req);
221225
zend_result php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded);
222226
zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int seeded);
223227

224-
EVP_MD * php_openssl_get_evp_md_from_algo(zend_long algo);
228+
const EVP_MD *php_openssl_get_evp_md_by_name(const char *name);
229+
const EVP_MD *php_openssl_get_evp_md_from_algo(zend_long algo);
230+
const EVP_CIPHER * php_openssl_get_evp_cipher_by_name(const char *name);
225231
const EVP_CIPHER * php_openssl_get_evp_cipher_from_algo(zend_long algo);
226232

227233
void php_openssl_backend_init(void);

0 commit comments

Comments
 (0)