diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index f45891ac362..426898862ea 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2749,7 +2749,7 @@ PHP_FUNCTION(openssl_pkcs7_read) goto clean_exit; } - p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL); + p7 = php_openssl_pem_read_bio_pkcs7(bio_in); if (p7 == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -3071,19 +3071,19 @@ PHP_FUNCTION(openssl_cms_verify) switch (encoding) { case ENCODING_PEM: - cms = PEM_read_bio_CMS(sigbio, NULL, 0, NULL); - datain = in; - break; - case ENCODING_DER: - cms = d2i_CMS_bio(sigbio, NULL); - datain = in; - break; - case ENCODING_SMIME: - cms = SMIME_read_CMS(sigbio, &datain); - break; - default: - php_error_docref(NULL, E_WARNING, "Unknown encoding"); - goto clean_exit; + cms = php_openssl_pem_read_bio_cms(sigbio); + datain = in; + break; + case ENCODING_DER: + cms = php_openssl_d2i_bio_cms(sigbio); + datain = in; + break; + case ENCODING_SMIME: + cms = php_openssl_smime_read_cms(sigbio, &datain); + break; + default: + php_error_docref(NULL, E_WARNING, "Unknown encoding"); + goto clean_exit; } if (cms == NULL) { php_openssl_store_errors(); @@ -3398,7 +3398,7 @@ PHP_FUNCTION(openssl_cms_read) goto clean_exit; } - cms = PEM_read_bio_CMS(bio_in, NULL, NULL, NULL); + cms = php_openssl_pem_read_bio_cms(bio_in); if (cms == NULL) { php_openssl_store_errors(); goto clean_exit; @@ -3703,13 +3703,13 @@ PHP_FUNCTION(openssl_cms_decrypt) switch (encoding) { case ENCODING_DER: - cms = d2i_CMS_bio(in, NULL); + cms = php_openssl_d2i_bio_cms(in); break; case ENCODING_PEM: - cms = PEM_read_bio_CMS(in, NULL, 0, NULL); + cms = php_openssl_pem_read_bio_cms(in); break; case ENCODING_SMIME: - cms = SMIME_read_CMS(in, &datain); + cms = php_openssl_smime_read_cms(in, &datain); break; default: zend_argument_value_error(5, "must be an OPENSSL_ENCODING_* constant"); diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 1cf82ee3c81..cde3848b40c 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -541,18 +541,14 @@ X509 *php_openssl_x509_from_str( php_openssl_store_errors(); return NULL; } - cert = PEM_read_bio_X509(in, NULL, NULL, NULL); + cert = php_openssl_pem_read_bio_x509(in); } else { in = BIO_new_mem_buf(ZSTR_VAL(cert_str), (int) ZSTR_LEN(cert_str)); if (in == NULL) { php_openssl_store_errors(); return NULL; } -#ifdef TYPEDEF_D2I_OF - cert = (X509 *) PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); -#else - cert = (X509 *) PEM_ASN1_read_bio((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); -#endif + cert = php_openssl_pem_read_asn1_bio_x509(in); } if (!BIO_free(in)) { @@ -1127,7 +1123,7 @@ X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num) return NULL; } - csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL); + csr = php_openssl_pem_read_bio_x509_req(in); if (csr == NULL) { php_openssl_store_errors(); } @@ -1158,7 +1154,7 @@ EVP_PKEY *php_openssl_extract_public_key(EVP_PKEY *priv_key) return NULL; } - EVP_PKEY *pub_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); + EVP_PKEY *pub_key = php_openssl_pem_read_bio_public_key(bio); BIO_free(bio); return pub_key; } @@ -1290,7 +1286,7 @@ EVP_PKEY *php_openssl_pkey_from_zval( zend_string_release_ex(val_str, false); TMP_CLEAN; } - key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL); + key = php_openssl_pem_read_bio_public_key(in); BIO_free(in); } } else { @@ -1308,12 +1304,12 @@ EVP_PKEY *php_openssl_pkey_from_zval( TMP_CLEAN; } if (passphrase == NULL) { - key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); + key = php_openssl_pem_read_bio_private_key(in, NULL, NULL); } else { struct php_openssl_pem_password password; password.key = passphrase; password.len = passphrase_len; - key = PEM_read_bio_PrivateKey(in, NULL, php_openssl_pem_password_cb, &password); + key = php_openssl_pem_read_bio_private_key(in, php_openssl_pem_password_cb, &password); } BIO_free(in); } diff --git a/ext/openssl/openssl_backend_v1.c b/ext/openssl/openssl_backend_v1.c index ea9bd231915..c15fff2f795 100644 --- a/ext/openssl/openssl_backend_v1.c +++ b/ext/openssl/openssl_backend_v1.c @@ -692,4 +692,49 @@ CONF *php_openssl_nconf_new(void) return NCONF_new(NULL); } +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in) +{ + return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); +} + +X509 *php_openssl_pem_read_bio_x509(BIO *in) +{ + return PEM_read_bio_X509(in, NULL, NULL, NULL); +} + +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in) +{ + return PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); +} + +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in) +{ + return PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); +} + +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PrivateKey(in, NULL, cb, u); +} + +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in) +{ + return PEM_read_bio_PKCS7(in, NULL, NULL, NULL); +} + +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in) +{ + return PEM_read_bio_CMS(in, NULL, NULL, NULL); +} + +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in) +{ + return d2i_CMS_bio(in, NULL); +} + +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont) +{ + return SMIME_read_CMS(bio, bcont); +} + #endif diff --git a/ext/openssl/openssl_backend_v3.c b/ext/openssl/openssl_backend_v3.c index 952257c2edc..16f145b2c5f 100644 --- a/ext/openssl/openssl_backend_v3.c +++ b/ext/openssl/openssl_backend_v3.c @@ -843,4 +843,126 @@ CONF *php_openssl_nconf_new(void) return NCONF_new_ex(PHP_OPENSSL_LIBCTX, NULL); } +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in) +{ + X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (x == NULL) { + return NULL; + } + + if (PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, (void **) &x, NULL, NULL) == NULL) { + X509_free(x); + return NULL; + } + + return x; +} + +X509 *php_openssl_pem_read_bio_x509(BIO *in) +{ + X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (x == NULL) { + return NULL; + } + + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { + X509_free(x); + return NULL; + } + + return x; +} + +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in) +{ + X509_REQ *xr = X509_REQ_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (xr == NULL) { + return NULL; + } + + if (PEM_read_bio_X509_REQ(in, &xr, NULL, NULL) == NULL) { + X509_REQ_free(xr); + return NULL; + } + + return xr; +} + +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in) +{ + return PEM_read_bio_PUBKEY_ex(in, NULL, NULL, NULL, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u) +{ + return PEM_read_bio_PrivateKey_ex(in, NULL, cb, u, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); +} + +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in) +{ + PKCS7 *p = PKCS7_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (p == NULL) { + return NULL; + } + + if (PEM_read_bio_PKCS7(in, &p, NULL, NULL) == NULL) { + PKCS7_free(p); + return NULL; + } + + return p; +} + +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (PEM_read_bio_CMS(in, &ci, NULL, NULL) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (d2i_CMS_bio(in, &ci) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont) +{ + CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ); + + if (ci == NULL) { + return NULL; + } + + if (SMIME_read_CMS_ex(bio, 0, bcont, &ci) == NULL) { + CMS_ContentInfo_free(ci); + return NULL; + } + + return ci; +} + #endif diff --git a/ext/openssl/php_openssl_backend.h b/ext/openssl/php_openssl_backend.h index 50f18e171c2..35af52c6c83 100644 --- a/ext/openssl/php_openssl_backend.h +++ b/ext/openssl/php_openssl_backend.h @@ -192,6 +192,16 @@ STACK_OF(X509) * php_openssl_load_all_certs_from_file( EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req); zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t requested_key_size); +X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in); +X509 *php_openssl_pem_read_bio_x509(BIO *in); +X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in); +EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in); +EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u); +PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in); +CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in); +CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in); +CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont); + #define PHP_SSL_REQ_INIT(req) memset(req, 0, sizeof(*req)) #define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req) #define PHP_SSL_REQ_PARSE(req, zval) php_openssl_parse_config(req, zval) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 65d28f210c5..84bfe895c3c 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -27,6 +27,7 @@ #include "streams/php_streams_int.h" #include "zend_smart_str.h" #include "php_openssl.h" +#include "php_openssl_backend.h" #include "php_network.h" #include #include @@ -850,7 +851,7 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c add_cert: { BIO_puts(buffer, line); efree(line); - cert = PEM_read_bio_X509(buffer, NULL, 0, NULL); + cert = php_openssl_pem_read_bio_x509(buffer); BIO_free(buffer); buffer_active = 0; if (cert && X509_STORE_add_cert(cert_store, cert)) {