Skip to content

Commit 2655b22

Browse files
committed
Use custom OpenSSL libctx in md and cipher handling code
1 parent 16a3fb1 commit 2655b22

File tree

5 files changed

+252
-114
lines changed

5 files changed

+252
-114
lines changed

ext/openssl/openssl.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ PHP_FUNCTION(openssl_spki_new)
583583
zval *zpkey = NULL;
584584
EVP_PKEY *pkey = NULL;
585585
NETSCAPE_SPKI *spki=NULL;
586-
const EVP_MD *mdtype;
586+
const EVP_MD *mdtype = NULL;
587587

588588
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Os|l", &zpkey, php_openssl_pkey_ce, &challenge, &challenge_len, &algo) == FAILURE) {
589589
RETURN_THROWS();
@@ -647,6 +647,7 @@ PHP_FUNCTION(openssl_spki_new)
647647
goto cleanup;
648648

649649
cleanup:
650+
php_openssl_release_evp_md(mdtype);
650651
EVP_PKEY_free(pkey);
651652
if (spki != NULL) {
652653
NETSCAPE_SPKI_free(spki);
@@ -1821,7 +1822,6 @@ PHP_FUNCTION(openssl_csr_sign)
18211822
X509_free(new_cert);
18221823
}
18231824

1824-
PHP_SSL_REQ_DISPOSE(&req);
18251825
EVP_PKEY_free(priv_key);
18261826
EVP_PKEY_free(key);
18271827
if (csr_str) {
@@ -1830,6 +1830,7 @@ PHP_FUNCTION(openssl_csr_sign)
18301830
if (cert_str && cert && cert != new_cert) {
18311831
X509_free(cert);
18321832
}
1833+
PHP_SSL_REQ_DISPOSE(&req);
18331834
}
18341835
/* }}} */
18351836

@@ -2104,7 +2105,8 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
21042105
}
21052106

21062107
if (!php_openssl_check_path(filename, filename_len, file_path, 2)) {
2107-
goto clean_exit_key;
2108+
EVP_PKEY_free(key);
2109+
return;
21082110
}
21092111

21102112
PHP_SSL_REQ_INIT(&req);
@@ -2139,10 +2141,9 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
21392141
}
21402142

21412143
clean_exit:
2142-
PHP_SSL_REQ_DISPOSE(&req);
21432144
BIO_free(bio_out);
2144-
clean_exit_key:
21452145
EVP_PKEY_free(key);
2146+
PHP_SSL_REQ_DISPOSE(&req);
21462147
}
21472148
/* }}} */
21482149

@@ -2204,9 +2205,9 @@ PHP_FUNCTION(openssl_pkey_export)
22042205
php_openssl_store_errors();
22052206
}
22062207
}
2207-
PHP_SSL_REQ_DISPOSE(&req);
22082208
EVP_PKEY_free(key);
22092209
BIO_free(bio_out);
2210+
PHP_SSL_REQ_DISPOSE(&req);
22102211
}
22112212
/* }}} */
22122213

@@ -2686,6 +2687,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
26862687
if (recipcerts) {
26872688
sk_X509_pop_free(recipcerts, X509_free);
26882689
}
2690+
php_openssl_release_evp_cipher(cipher);
26892691
}
26902692
/* }}} */
26912693

@@ -3334,6 +3336,7 @@ PHP_FUNCTION(openssl_cms_encrypt)
33343336
if (recipcerts) {
33353337
sk_X509_pop_free(recipcerts, X509_free);
33363338
}
3339+
php_openssl_release_evp_cipher(cipher);
33373340
}
33383341
/* }}} */
33393342

@@ -3969,7 +3972,7 @@ PHP_FUNCTION(openssl_sign)
39693972
}
39703973

39713974
if (method_str) {
3972-
mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str));
3975+
mdtype = php_openssl_get_evp_md_by_name(ZSTR_VAL(method_str));
39733976
} else {
39743977
mdtype = php_openssl_get_evp_md_from_algo(method_long);
39753978
}
@@ -3996,6 +3999,7 @@ PHP_FUNCTION(openssl_sign)
39963999
RETVAL_FALSE;
39974000
}
39984001
EVP_MD_CTX_destroy(md_ctx);
4002+
php_openssl_release_evp_md(mdtype);
39994003
EVP_PKEY_free(pkey);
40004004
}
40014005
/* }}} */
@@ -4027,7 +4031,7 @@ PHP_FUNCTION(openssl_verify)
40274031
PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature, 2);
40284032

40294033
if (method_str) {
4030-
mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str));
4034+
mdtype = php_openssl_get_evp_md_by_name(ZSTR_VAL(method_str));
40314035
} else {
40324036
mdtype = php_openssl_get_evp_md_from_algo(method_long);
40334037
}
@@ -4041,6 +4045,7 @@ PHP_FUNCTION(openssl_verify)
40414045
if (!EG(exception)) {
40424046
php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a public key");
40434047
}
4048+
php_openssl_release_evp_md(mdtype);
40444049
RETURN_FALSE;
40454050
}
40464051

@@ -4051,6 +4056,7 @@ PHP_FUNCTION(openssl_verify)
40514056
php_openssl_store_errors();
40524057
}
40534058
EVP_MD_CTX_destroy(md_ctx);
4059+
php_openssl_release_evp_md(mdtype);
40544060
EVP_PKEY_free(pkey);
40554061
RETURN_LONG(err);
40564062
}
@@ -4323,7 +4329,7 @@ PHP_FUNCTION(openssl_digest)
43234329
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|b", &data, &data_len, &method, &method_len, &raw_output) == FAILURE) {
43244330
RETURN_THROWS();
43254331
}
4326-
mdtype = EVP_get_digestbyname(method);
4332+
mdtype = php_openssl_get_evp_md_by_name(method);
43274333
if (!mdtype) {
43284334
php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
43294335
RETURN_FALSE;
@@ -4356,6 +4362,7 @@ PHP_FUNCTION(openssl_digest)
43564362
}
43574363

43584364
EVP_MD_CTX_destroy(md_ctx);
4365+
php_openssl_release_evp_md(mdtype);
43594366
}
43604367
/* }}} */
43614368

ext/openssl/openssl_backend_common.c

Lines changed: 28 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -369,11 +369,11 @@ int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args
369369
if (strcmp(req->digest_name, "null") == 0) {
370370
req->digest = req->md_alg = EVP_md_null();
371371
} else {
372-
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
372+
req->digest = req->md_alg = php_openssl_get_evp_md_by_name(req->digest_name);
373373
}
374374
}
375375
if (req->md_alg == NULL) {
376-
req->md_alg = req->digest = EVP_sha1();
376+
req->md_alg = req->digest = php_openssl_get_evp_md_by_name("sha1");
377377
php_openssl_store_errors();
378378
}
379379

@@ -417,6 +417,10 @@ void php_openssl_dispose_config(struct php_x509_request * req)
417417
NCONF_free(req->req_config);
418418
req->req_config = NULL;
419419
}
420+
if (req->md_alg != NULL && req->md_alg != EVP_md_null()) {
421+
php_openssl_release_evp_md(req->md_alg);
422+
}
423+
php_openssl_release_evp_cipher(req->priv_key_encrypt_cipher);
420424
}
421425

422426
zend_result php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded)
@@ -469,92 +473,6 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se
469473
return SUCCESS;
470474
}
471475

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-
558476
void php_openssl_backend_init(void)
559477
{
560478
#ifdef LIBRESSL_VERSION_NUMBER
@@ -1931,14 +1849,15 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt(
19311849
PHP_OPENSSL_CHECK_LONG_TO_INT_NULL_RETURN(tag_len, tag_len);
19321850

19331851

1934-
cipher_type = EVP_get_cipherbyname(method);
1852+
cipher_type = php_openssl_get_evp_cipher_by_name(method);
19351853
if (!cipher_type) {
19361854
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
19371855
return NULL;
19381856
}
19391857

19401858
cipher_ctx = EVP_CIPHER_CTX_new();
19411859
if (!cipher_ctx) {
1860+
php_openssl_release_evp_cipher(cipher_type);
19421861
php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
19431862
return NULL;
19441863
}
@@ -1997,6 +1916,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt(
19971916
}
19981917
EVP_CIPHER_CTX_reset(cipher_ctx);
19991918
EVP_CIPHER_CTX_free(cipher_ctx);
1919+
php_openssl_release_evp_cipher(cipher_type);
20001920
return outbuf;
20011921
}
20021922

@@ -2023,14 +1943,15 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt(
20231943
PHP_OPENSSL_CHECK_SIZE_T_TO_INT_NULL_RETURN(tag_len, tag);
20241944

20251945

2026-
cipher_type = EVP_get_cipherbyname(method);
1946+
cipher_type = php_openssl_get_evp_cipher_by_name(method);
20271947
if (!cipher_type) {
20281948
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
20291949
return NULL;
20301950
}
20311951

20321952
cipher_ctx = EVP_CIPHER_CTX_new();
20331953
if (!cipher_ctx) {
1954+
php_openssl_release_evp_cipher(cipher_type);
20341955
php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
20351956
return NULL;
20361957
}
@@ -2076,14 +1997,15 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt(
20761997
}
20771998
EVP_CIPHER_CTX_reset(cipher_ctx);
20781999
EVP_CIPHER_CTX_free(cipher_ctx);
2000+
php_openssl_release_evp_cipher(cipher_type);
20792001
return outbuf;
20802002
}
20812003

2082-
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method)
2004+
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name_with_warning(const char *method)
20832005
{
20842006
const EVP_CIPHER *cipher_type;
20852007

2086-
cipher_type = EVP_get_cipherbyname(method);
2008+
cipher_type = php_openssl_get_evp_cipher_by_name(method);
20872009
if (!cipher_type) {
20882010
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
20892011
return NULL;
@@ -2095,16 +2017,26 @@ const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method)
20952017

20962018
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method)
20972019
{
2098-
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
2020+
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name_with_warning(method);
2021+
if (cipher_type == NULL) {
2022+
return -1;
2023+
}
2024+
int iv_length = EVP_CIPHER_iv_length(cipher_type);
2025+
php_openssl_release_evp_cipher(cipher_type);
20992026

2100-
return cipher_type == NULL ? -1 : EVP_CIPHER_iv_length(cipher_type);
2027+
return iv_length;
21012028
}
21022029

21032030
PHP_OPENSSL_API zend_long php_openssl_cipher_key_length(const char *method)
21042031
{
2105-
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
2032+
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name_with_warning(method);
2033+
if (cipher_type == NULL) {
2034+
return -1;
2035+
}
2036+
int key_length = EVP_CIPHER_key_length(cipher_type);
2037+
php_openssl_release_evp_cipher(cipher_type);
21062038

2107-
return cipher_type == NULL ? -1 : EVP_CIPHER_key_length(cipher_type);
2039+
return key_length;
21082040
}
21092041

21102042
PHP_OPENSSL_API zend_string* php_openssl_random_pseudo_bytes(zend_long buffer_length)

0 commit comments

Comments
 (0)