From: Nikita Popov Date: Fri, 21 Jun 2019 12:17:05 +0000 (+0200) Subject: Fix CSR leaks in openssl X-Git-Tag: php-7.2.21RC1~33 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0bafc6da440f5b028453ca19d012d6a02234fc8;p=php Fix CSR leaks in openssl --- diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 91df229c3d..d266220d3e 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3619,7 +3619,10 @@ PHP_FUNCTION(openssl_csr_get_subject) array_init(return_value); php_openssl_add_assoc_name_entry(return_value, NULL, subject, use_shortnames); - return; + + if (!csr_resource) { + X509_REQ_free(csr); + } } /* }}} */ @@ -3631,16 +3634,16 @@ PHP_FUNCTION(openssl_csr_get_public_key) zend_bool use_shortnames = 1; zend_resource *csr_resource; - X509_REQ * csr; + X509_REQ *orig_csr, *csr; EVP_PKEY *tpubkey; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|b", &zcsr, &use_shortnames) == FAILURE) { return; } - csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); + orig_csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource); - if (csr == NULL) { + if (orig_csr == NULL) { RETURN_FALSE; } @@ -3650,15 +3653,23 @@ PHP_FUNCTION(openssl_csr_get_public_key) * a private key, it will be returned including the private part. * If we duplicate it, then we get just the public part which is * the same behavior as for OpenSSL 1.0 */ - csr = X509_REQ_dup(csr); + csr = X509_REQ_dup(orig_csr); +#else + csr = orig_csr; #endif + /* Retrieve the public key from the CSR */ tpubkey = X509_REQ_get_pubkey(csr); -#if PHP_OPENSSL_API_VERSION >= 0x10100 - /* We need to free the CSR as it was duplicated */ - X509_REQ_free(csr); -#endif + if (csr != orig_csr) { + /* We need to free the duplicated CSR */ + X509_REQ_free(csr); + } + + if (!csr_resource) { + /* We also need to free the original CSR if it was freshly created */ + X509_REQ_free(orig_csr); + } if (tpubkey == NULL) { php_openssl_store_errors();