Skip to content

Commit c5f79b8

Browse files
authored
Use OpenSSL libctx for various BIO readers (#19448)
This converts mostly PEM readers but also DER for CMS
1 parent 6280dfc commit c5f79b8

File tree

6 files changed

+204
-30
lines changed

6 files changed

+204
-30
lines changed

ext/openssl/openssl.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2749,7 +2749,7 @@ PHP_FUNCTION(openssl_pkcs7_read)
27492749
goto clean_exit;
27502750
}
27512751

2752-
p7 = PEM_read_bio_PKCS7(bio_in, NULL, NULL, NULL);
2752+
p7 = php_openssl_pem_read_bio_pkcs7(bio_in);
27532753
if (p7 == NULL) {
27542754
php_openssl_store_errors();
27552755
goto clean_exit;
@@ -3071,19 +3071,19 @@ PHP_FUNCTION(openssl_cms_verify)
30713071

30723072
switch (encoding) {
30733073
case ENCODING_PEM:
3074-
cms = PEM_read_bio_CMS(sigbio, NULL, 0, NULL);
3075-
datain = in;
3076-
break;
3077-
case ENCODING_DER:
3078-
cms = d2i_CMS_bio(sigbio, NULL);
3079-
datain = in;
3080-
break;
3081-
case ENCODING_SMIME:
3082-
cms = SMIME_read_CMS(sigbio, &datain);
3083-
break;
3084-
default:
3085-
php_error_docref(NULL, E_WARNING, "Unknown encoding");
3086-
goto clean_exit;
3074+
cms = php_openssl_pem_read_bio_cms(sigbio);
3075+
datain = in;
3076+
break;
3077+
case ENCODING_DER:
3078+
cms = php_openssl_d2i_bio_cms(sigbio);
3079+
datain = in;
3080+
break;
3081+
case ENCODING_SMIME:
3082+
cms = php_openssl_smime_read_cms(sigbio, &datain);
3083+
break;
3084+
default:
3085+
php_error_docref(NULL, E_WARNING, "Unknown encoding");
3086+
goto clean_exit;
30873087
}
30883088
if (cms == NULL) {
30893089
php_openssl_store_errors();
@@ -3398,7 +3398,7 @@ PHP_FUNCTION(openssl_cms_read)
33983398
goto clean_exit;
33993399
}
34003400

3401-
cms = PEM_read_bio_CMS(bio_in, NULL, NULL, NULL);
3401+
cms = php_openssl_pem_read_bio_cms(bio_in);
34023402
if (cms == NULL) {
34033403
php_openssl_store_errors();
34043404
goto clean_exit;
@@ -3703,13 +3703,13 @@ PHP_FUNCTION(openssl_cms_decrypt)
37033703

37043704
switch (encoding) {
37053705
case ENCODING_DER:
3706-
cms = d2i_CMS_bio(in, NULL);
3706+
cms = php_openssl_d2i_bio_cms(in);
37073707
break;
37083708
case ENCODING_PEM:
3709-
cms = PEM_read_bio_CMS(in, NULL, 0, NULL);
3709+
cms = php_openssl_pem_read_bio_cms(in);
37103710
break;
37113711
case ENCODING_SMIME:
3712-
cms = SMIME_read_CMS(in, &datain);
3712+
cms = php_openssl_smime_read_cms(in, &datain);
37133713
break;
37143714
default:
37153715
zend_argument_value_error(5, "must be an OPENSSL_ENCODING_* constant");

ext/openssl/openssl_backend_common.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -541,18 +541,14 @@ X509 *php_openssl_x509_from_str(
541541
php_openssl_store_errors();
542542
return NULL;
543543
}
544-
cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
544+
cert = php_openssl_pem_read_bio_x509(in);
545545
} else {
546546
in = BIO_new_mem_buf(ZSTR_VAL(cert_str), (int) ZSTR_LEN(cert_str));
547547
if (in == NULL) {
548548
php_openssl_store_errors();
549549
return NULL;
550550
}
551-
#ifdef TYPEDEF_D2I_OF
552-
cert = (X509 *) PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL);
553-
#else
554-
cert = (X509 *) PEM_ASN1_read_bio((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL);
555-
#endif
551+
cert = php_openssl_pem_read_asn1_bio_x509(in);
556552
}
557553

558554
if (!BIO_free(in)) {
@@ -1127,7 +1123,7 @@ X509_REQ *php_openssl_csr_from_str(zend_string *csr_str, uint32_t arg_num)
11271123
return NULL;
11281124
}
11291125

1130-
csr = PEM_read_bio_X509_REQ(in, NULL,NULL,NULL);
1126+
csr = php_openssl_pem_read_bio_x509_req(in);
11311127
if (csr == NULL) {
11321128
php_openssl_store_errors();
11331129
}
@@ -1158,7 +1154,7 @@ EVP_PKEY *php_openssl_extract_public_key(EVP_PKEY *priv_key)
11581154
return NULL;
11591155
}
11601156

1161-
EVP_PKEY *pub_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
1157+
EVP_PKEY *pub_key = php_openssl_pem_read_bio_public_key(bio);
11621158
BIO_free(bio);
11631159
return pub_key;
11641160
}
@@ -1290,7 +1286,7 @@ EVP_PKEY *php_openssl_pkey_from_zval(
12901286
zend_string_release_ex(val_str, false);
12911287
TMP_CLEAN;
12921288
}
1293-
key = PEM_read_bio_PUBKEY(in, NULL,NULL, NULL);
1289+
key = php_openssl_pem_read_bio_public_key(in);
12941290
BIO_free(in);
12951291
}
12961292
} else {
@@ -1308,12 +1304,12 @@ EVP_PKEY *php_openssl_pkey_from_zval(
13081304
TMP_CLEAN;
13091305
}
13101306
if (passphrase == NULL) {
1311-
key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1307+
key = php_openssl_pem_read_bio_private_key(in, NULL, NULL);
13121308
} else {
13131309
struct php_openssl_pem_password password;
13141310
password.key = passphrase;
13151311
password.len = passphrase_len;
1316-
key = PEM_read_bio_PrivateKey(in, NULL, php_openssl_pem_password_cb, &password);
1312+
key = php_openssl_pem_read_bio_private_key(in, php_openssl_pem_password_cb, &password);
13171313
}
13181314
BIO_free(in);
13191315
}

ext/openssl/openssl_backend_v1.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,4 +692,49 @@ CONF *php_openssl_nconf_new(void)
692692
return NCONF_new(NULL);
693693
}
694694

695+
X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in)
696+
{
697+
return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL);
698+
}
699+
700+
X509 *php_openssl_pem_read_bio_x509(BIO *in)
701+
{
702+
return PEM_read_bio_X509(in, NULL, NULL, NULL);
703+
}
704+
705+
X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in)
706+
{
707+
return PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
708+
}
709+
710+
EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in)
711+
{
712+
return PEM_read_bio_PUBKEY(in, NULL, NULL, NULL);
713+
}
714+
715+
EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u)
716+
{
717+
return PEM_read_bio_PrivateKey(in, NULL, cb, u);
718+
}
719+
720+
PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in)
721+
{
722+
return PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
723+
}
724+
725+
CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in)
726+
{
727+
return PEM_read_bio_CMS(in, NULL, NULL, NULL);
728+
}
729+
730+
CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in)
731+
{
732+
return d2i_CMS_bio(in, NULL);
733+
}
734+
735+
CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont)
736+
{
737+
return SMIME_read_CMS(bio, bcont);
738+
}
739+
695740
#endif

ext/openssl/openssl_backend_v3.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,4 +843,126 @@ CONF *php_openssl_nconf_new(void)
843843
return NCONF_new_ex(PHP_OPENSSL_LIBCTX, NULL);
844844
}
845845

846+
X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in)
847+
{
848+
X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
849+
850+
if (x == NULL) {
851+
return NULL;
852+
}
853+
854+
if (PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, (void **) &x, NULL, NULL) == NULL) {
855+
X509_free(x);
856+
return NULL;
857+
}
858+
859+
return x;
860+
}
861+
862+
X509 *php_openssl_pem_read_bio_x509(BIO *in)
863+
{
864+
X509 *x = X509_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
865+
866+
if (x == NULL) {
867+
return NULL;
868+
}
869+
870+
if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
871+
X509_free(x);
872+
return NULL;
873+
}
874+
875+
return x;
876+
}
877+
878+
X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in)
879+
{
880+
X509_REQ *xr = X509_REQ_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
881+
882+
if (xr == NULL) {
883+
return NULL;
884+
}
885+
886+
if (PEM_read_bio_X509_REQ(in, &xr, NULL, NULL) == NULL) {
887+
X509_REQ_free(xr);
888+
return NULL;
889+
}
890+
891+
return xr;
892+
}
893+
894+
EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in)
895+
{
896+
return PEM_read_bio_PUBKEY_ex(in, NULL, NULL, NULL, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
897+
}
898+
899+
EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u)
900+
{
901+
return PEM_read_bio_PrivateKey_ex(in, NULL, cb, u, PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
902+
}
903+
904+
PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in)
905+
{
906+
PKCS7 *p = PKCS7_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
907+
908+
if (p == NULL) {
909+
return NULL;
910+
}
911+
912+
if (PEM_read_bio_PKCS7(in, &p, NULL, NULL) == NULL) {
913+
PKCS7_free(p);
914+
return NULL;
915+
}
916+
917+
return p;
918+
}
919+
920+
CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in)
921+
{
922+
CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
923+
924+
if (ci == NULL) {
925+
return NULL;
926+
}
927+
928+
if (PEM_read_bio_CMS(in, &ci, NULL, NULL) == NULL) {
929+
CMS_ContentInfo_free(ci);
930+
return NULL;
931+
}
932+
933+
return ci;
934+
}
935+
936+
CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in)
937+
{
938+
CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
939+
940+
if (ci == NULL) {
941+
return NULL;
942+
}
943+
944+
if (d2i_CMS_bio(in, &ci) == NULL) {
945+
CMS_ContentInfo_free(ci);
946+
return NULL;
947+
}
948+
949+
return ci;
950+
}
951+
952+
CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont)
953+
{
954+
CMS_ContentInfo *ci = CMS_ContentInfo_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ);
955+
956+
if (ci == NULL) {
957+
return NULL;
958+
}
959+
960+
if (SMIME_read_CMS_ex(bio, 0, bcont, &ci) == NULL) {
961+
CMS_ContentInfo_free(ci);
962+
return NULL;
963+
}
964+
965+
return ci;
966+
}
967+
846968
#endif

ext/openssl/php_openssl_backend.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ STACK_OF(X509) * php_openssl_load_all_certs_from_file(
192192
EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req);
193193
zend_string *php_openssl_pkey_derive(EVP_PKEY *key, EVP_PKEY *peer_key, size_t requested_key_size);
194194

195+
X509 *php_openssl_pem_read_asn1_bio_x509(BIO *in);
196+
X509 *php_openssl_pem_read_bio_x509(BIO *in);
197+
X509_REQ *php_openssl_pem_read_bio_x509_req(BIO *in);
198+
EVP_PKEY *php_openssl_pem_read_bio_public_key(BIO *in);
199+
EVP_PKEY *php_openssl_pem_read_bio_private_key(BIO *in, pem_password_cb *cb, void *u);
200+
PKCS7 *php_openssl_pem_read_bio_pkcs7(BIO *in);
201+
CMS_ContentInfo *php_openssl_pem_read_bio_cms(BIO *in);
202+
CMS_ContentInfo *php_openssl_d2i_bio_cms(BIO *in);
203+
CMS_ContentInfo *php_openssl_smime_read_cms(BIO *bio, BIO **bcont);
204+
195205
#define PHP_SSL_REQ_INIT(req) memset(req, 0, sizeof(*req))
196206
#define PHP_SSL_REQ_DISPOSE(req) php_openssl_dispose_config(req)
197207
#define PHP_SSL_REQ_PARSE(req, zval) php_openssl_parse_config(req, zval)

ext/openssl/xp_ssl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "streams/php_streams_int.h"
2828
#include "zend_smart_str.h"
2929
#include "php_openssl.h"
30+
#include "php_openssl_backend.h"
3031
#include "php_network.h"
3132
#include <openssl/ssl.h>
3233
#include <openssl/rsa.h>
@@ -850,7 +851,7 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c
850851
add_cert: {
851852
BIO_puts(buffer, line);
852853
efree(line);
853-
cert = PEM_read_bio_X509(buffer, NULL, 0, NULL);
854+
cert = php_openssl_pem_read_bio_x509(buffer);
854855
BIO_free(buffer);
855856
buffer_active = 0;
856857
if (cert && X509_STORE_add_cert(cert_store, cert)) {

0 commit comments

Comments
 (0)