From 90cb3743be293aab801a78196ad038c039786c19 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Jun 2019 14:03:06 +0200 Subject: [PATCH 1/6] Free cert in php_openssl_load_stream_cafile() X509_STORE_add_cert() increments the refcount of the cert, so we should free it here. --- ext/openssl/xp_ssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index a423da6e741..c8e5692bbe0 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -827,6 +827,7 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c buffer_active = 0; if (cert && X509_STORE_add_cert(cert_store, cert)) { ++certs_added; + X509_free(cert); } goto cert_start; } From e0bafc6da440f5b028453ca19d012d6a02234fc8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Jun 2019 14:17:05 +0200 Subject: [PATCH 2/6] Fix CSR leaks in openssl --- ext/openssl/openssl.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 91df229c3d4..d266220d3ea 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(); From a0da2fb2b78b4783666be2c82d5eda23f9f65552 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Jun 2019 14:24:00 +0200 Subject: [PATCH 3/6] Fix X509 leak in openssl_pkcs7_verify() --- ext/openssl/openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index d266220d3ea..855c093f344 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -5150,7 +5150,7 @@ clean_exit: BIO_free(in); BIO_free(dataout); PKCS7_free(p7); - sk_X509_free(others); + sk_X509_pop_free(others, X509_free); } /* }}} */ From dfe6f0c1c6838d1fd9e6be49fd6896d421b4dac8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Jun 2019 14:35:35 +0200 Subject: [PATCH 4/6] Fix netscape spki leak in openssl --- ext/openssl/openssl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 855c093f344..69120f35591 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2076,6 +2076,9 @@ cleanup: if (spkstr_cleaned != NULL) { efree(spkstr_cleaned); } + if (spki) { + NETSCAPE_SPKI_free(spki); + } } /* }}} */ From c939a67866536247325b204929d8b9cac021c71e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Jun 2019 14:43:15 +0200 Subject: [PATCH 5/6] Fix d leak in ecc openssl_pkey_new --- ext/openssl/openssl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 69120f35591..c1560fa884b 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4370,7 +4370,7 @@ PHP_FUNCTION(openssl_pkey_new) EC_KEY *eckey = NULL; EC_GROUP *group = NULL; EC_POINT *pnt = NULL; - const BIGNUM *d; + BIGNUM *d = NULL; pkey = EVP_PKEY_new(); if (pkey) { eckey = EC_KEY_new(); @@ -4418,6 +4418,8 @@ PHP_FUNCTION(openssl_pkey_new) php_openssl_store_errors(); goto clean_exit; } + + BN_free(d); } else if ((x = zend_hash_str_find(Z_ARRVAL_P(data), "x", sizeof("x") - 1)) != NULL && Z_TYPE_P(x) == IS_STRING && (y = zend_hash_str_find(Z_ARRVAL_P(data), "y", sizeof("y") - 1)) != NULL && @@ -4462,6 +4464,9 @@ PHP_FUNCTION(openssl_pkey_new) php_openssl_store_errors(); } clean_exit: + if (d != NULL) { + BN_free(d); + } if (pnt != NULL) { EC_POINT_free(pnt); } From 99f3e0f0ed6668097bf4fb2820f3e97db1197869 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 21 Jun 2019 15:00:25 +0200 Subject: [PATCH 6/6] Fix PKCS12 leak in openssl --- ext/openssl/openssl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index c1560fa884b..6c1dd9d3435 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3029,8 +3029,6 @@ PHP_FUNCTION(openssl_pkcs12_read) } RETVAL_TRUE; - - PKCS12_free(p12); } else { php_openssl_store_errors(); } @@ -3045,6 +3043,9 @@ PHP_FUNCTION(openssl_pkcs12_read) if (cert) { X509_free(cert); } + if (p12) { + PKCS12_free(p12); + } } /* }}} */