Skip to content

Use custom OpenSSL libctx in md and cipher handling code #18516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions ext/openssl/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ PHP_FUNCTION(openssl_spki_new)
zval *zpkey = NULL;
EVP_PKEY *pkey = NULL;
NETSCAPE_SPKI *spki=NULL;
const EVP_MD *mdtype;
const EVP_MD *mdtype = NULL;

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

cleanup:
php_openssl_release_evp_md(mdtype);
EVP_PKEY_free(pkey);
if (spki != NULL) {
NETSCAPE_SPKI_free(spki);
Expand Down Expand Up @@ -1821,7 +1822,6 @@ PHP_FUNCTION(openssl_csr_sign)
X509_free(new_cert);
}

PHP_SSL_REQ_DISPOSE(&req);
EVP_PKEY_free(priv_key);
EVP_PKEY_free(key);
if (csr_str) {
Expand All @@ -1830,6 +1830,7 @@ PHP_FUNCTION(openssl_csr_sign)
if (cert_str && cert && cert != new_cert) {
X509_free(cert);
}
PHP_SSL_REQ_DISPOSE(&req);
}
/* }}} */

Expand Down Expand Up @@ -2104,7 +2105,8 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
}

if (!php_openssl_check_path(filename, filename_len, file_path, 2)) {
goto clean_exit_key;
EVP_PKEY_free(key);
return;
}

PHP_SSL_REQ_INIT(&req);
Expand Down Expand Up @@ -2139,10 +2141,9 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
}

clean_exit:
PHP_SSL_REQ_DISPOSE(&req);
BIO_free(bio_out);
clean_exit_key:
EVP_PKEY_free(key);
PHP_SSL_REQ_DISPOSE(&req);
}
/* }}} */

Expand Down Expand Up @@ -2204,9 +2205,9 @@ PHP_FUNCTION(openssl_pkey_export)
php_openssl_store_errors();
}
}
PHP_SSL_REQ_DISPOSE(&req);
EVP_PKEY_free(key);
BIO_free(bio_out);
PHP_SSL_REQ_DISPOSE(&req);
}
/* }}} */

Expand Down Expand Up @@ -2686,6 +2687,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
if (recipcerts) {
sk_X509_pop_free(recipcerts, X509_free);
}
php_openssl_release_evp_cipher(cipher);
}
/* }}} */

Expand Down Expand Up @@ -3334,6 +3336,7 @@ PHP_FUNCTION(openssl_cms_encrypt)
if (recipcerts) {
sk_X509_pop_free(recipcerts, X509_free);
}
php_openssl_release_evp_cipher(cipher);
}
/* }}} */

Expand Down Expand Up @@ -3969,7 +3972,7 @@ PHP_FUNCTION(openssl_sign)
}

if (method_str) {
mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str));
mdtype = php_openssl_get_evp_md_by_name(ZSTR_VAL(method_str));
} else {
mdtype = php_openssl_get_evp_md_from_algo(method_long);
}
Expand All @@ -3996,6 +3999,7 @@ PHP_FUNCTION(openssl_sign)
RETVAL_FALSE;
}
EVP_MD_CTX_destroy(md_ctx);
php_openssl_release_evp_md(mdtype);
EVP_PKEY_free(pkey);
}
/* }}} */
Expand Down Expand Up @@ -4027,7 +4031,7 @@ PHP_FUNCTION(openssl_verify)
PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature, 2);

if (method_str) {
mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str));
mdtype = php_openssl_get_evp_md_by_name(ZSTR_VAL(method_str));
} else {
mdtype = php_openssl_get_evp_md_from_algo(method_long);
}
Expand All @@ -4041,6 +4045,7 @@ PHP_FUNCTION(openssl_verify)
if (!EG(exception)) {
php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a public key");
}
php_openssl_release_evp_md(mdtype);
RETURN_FALSE;
}

Expand All @@ -4051,6 +4056,7 @@ PHP_FUNCTION(openssl_verify)
php_openssl_store_errors();
}
EVP_MD_CTX_destroy(md_ctx);
php_openssl_release_evp_md(mdtype);
EVP_PKEY_free(pkey);
RETURN_LONG(err);
}
Expand Down Expand Up @@ -4323,7 +4329,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;
Expand Down Expand Up @@ -4356,6 +4362,7 @@ PHP_FUNCTION(openssl_digest)
}

EVP_MD_CTX_destroy(md_ctx);
php_openssl_release_evp_md(mdtype);
}
/* }}} */

Expand Down
124 changes: 28 additions & 96 deletions ext/openssl/openssl_backend_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,11 @@ int php_openssl_parse_config(struct php_x509_request * req, zval * optional_args
if (strcmp(req->digest_name, "null") == 0) {
req->digest = req->md_alg = EVP_md_null();
} else {
req->digest = req->md_alg = EVP_get_digestbyname(req->digest_name);
req->digest = req->md_alg = php_openssl_get_evp_md_by_name(req->digest_name);
}
}
if (req->md_alg == NULL) {
req->md_alg = req->digest = EVP_sha1();
req->md_alg = req->digest = php_openssl_get_evp_md_by_name("sha1");
php_openssl_store_errors();
}

Expand Down Expand Up @@ -417,6 +417,10 @@ void php_openssl_dispose_config(struct php_x509_request * req)
NCONF_free(req->req_config);
req->req_config = NULL;
}
if (req->md_alg != NULL && req->md_alg != EVP_md_null()) {
php_openssl_release_evp_md(req->md_alg);
}
php_openssl_release_evp_cipher(req->priv_key_encrypt_cipher);
}

zend_result php_openssl_load_rand_file(const char * file, int *egdsocket, int *seeded)
Expand Down Expand Up @@ -469,92 +473,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
Expand Down Expand Up @@ -1931,14 +1849,15 @@ 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;
}

cipher_ctx = EVP_CIPHER_CTX_new();
if (!cipher_ctx) {
php_openssl_release_evp_cipher(cipher_type);
php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
return NULL;
}
Expand Down Expand Up @@ -1997,6 +1916,7 @@ PHP_OPENSSL_API zend_string* php_openssl_encrypt(
}
EVP_CIPHER_CTX_reset(cipher_ctx);
EVP_CIPHER_CTX_free(cipher_ctx);
php_openssl_release_evp_cipher(cipher_type);
return outbuf;
}

Expand All @@ -2023,14 +1943,15 @@ 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;
}

cipher_ctx = EVP_CIPHER_CTX_new();
if (!cipher_ctx) {
php_openssl_release_evp_cipher(cipher_type);
php_error_docref(NULL, E_WARNING, "Failed to create cipher context");
return NULL;
}
Expand Down Expand Up @@ -2076,14 +1997,15 @@ PHP_OPENSSL_API zend_string* php_openssl_decrypt(
}
EVP_CIPHER_CTX_reset(cipher_ctx);
EVP_CIPHER_CTX_free(cipher_ctx);
php_openssl_release_evp_cipher(cipher_type);
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;
Expand All @@ -2095,16 +2017,26 @@ 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);
if (cipher_type == NULL) {
return -1;
}
int iv_length = EVP_CIPHER_iv_length(cipher_type);
php_openssl_release_evp_cipher(cipher_type);

return cipher_type == NULL ? -1 : EVP_CIPHER_iv_length(cipher_type);
return iv_length;
}

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);
if (cipher_type == NULL) {
return -1;
}
int key_length = EVP_CIPHER_key_length(cipher_type);
php_openssl_release_evp_cipher(cipher_type);

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

PHP_OPENSSL_API zend_string* php_openssl_random_pseudo_bytes(zend_long buffer_length)
Expand Down
Loading