Skip to content

Commit c349c32

Browse files
authored
Openssl little optims (#21424)
- reuse BIO object in certificate chain loops. Avoid repeated BIO_new/BIO_free per iteration in PKCS12, PKCS7, and CMS read functions. Allocate once before the loop, BIO_reset between iterations, free after. - Avoid double zval_get_long() call in threads option parsing. - Reuse already computed string length instead of calling strlen() again.
1 parent 85b23b0 commit c349c32

File tree

3 files changed

+43
-17
lines changed

3 files changed

+43
-17
lines changed

ext/openssl/openssl.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,10 @@ PHP_FUNCTION(openssl_pkcs12_read)
15311531

15321532
if (pkey) {
15331533
bio_out = BIO_new(BIO_s_mem());
1534+
if (!bio_out) {
1535+
goto cleanup;
1536+
}
1537+
15341538
if (PEM_write_bio_PrivateKey(bio_out, pkey, NULL, NULL, 0, 0, NULL)) {
15351539
BUF_MEM *bio_buf;
15361540
BIO_get_mem_ptr(bio_out, &bio_buf);
@@ -1545,23 +1549,27 @@ PHP_FUNCTION(openssl_pkcs12_read)
15451549
cert_num = sk_X509_num(ca);
15461550
if (ca && cert_num) {
15471551
array_init(&zextracerts);
1552+
bio_out = BIO_new(BIO_s_mem());
1553+
if (!bio_out) {
1554+
goto cleanup;
1555+
}
15481556

15491557
for (i = 0; i < cert_num; i++) {
15501558
zval zextracert;
15511559
X509* aCA = sk_X509_pop(ca);
15521560
if (!aCA) break;
15531561

1554-
bio_out = BIO_new(BIO_s_mem());
15551562
if (PEM_write_bio_X509(bio_out, aCA)) {
15561563
BUF_MEM *bio_buf;
15571564
BIO_get_mem_ptr(bio_out, &bio_buf);
15581565
ZVAL_STRINGL(&zextracert, bio_buf->data, bio_buf->length);
15591566
add_index_zval(&zextracerts, i, &zextracert);
15601567
}
15611568

1569+
BIO_reset(bio_out);
15621570
X509_free(aCA);
1563-
BIO_free(bio_out);
15641571
}
1572+
BIO_free(bio_out);
15651573

15661574
sk_X509_free(ca);
15671575
add_assoc_zval(zout, "extracerts", &zextracerts);
@@ -2814,33 +2822,41 @@ PHP_FUNCTION(openssl_pkcs7_read)
28142822
}
28152823

28162824
if (certs != NULL) {
2825+
bio_out = BIO_new(BIO_s_mem());
2826+
if (!bio_out) {
2827+
goto clean_exit;
2828+
}
28172829
for (i = 0; i < sk_X509_num(certs); i++) {
28182830
X509* ca = sk_X509_value(certs, i);
28192831

2820-
bio_out = BIO_new(BIO_s_mem());
2821-
if (bio_out && PEM_write_bio_X509(bio_out, ca)) {
2832+
if (PEM_write_bio_X509(bio_out, ca)) {
28222833
BUF_MEM *bio_buf;
28232834
BIO_get_mem_ptr(bio_out, &bio_buf);
28242835
ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
28252836
add_index_zval(zout, i, &zcert);
28262837
}
2827-
BIO_free(bio_out);
2838+
BIO_reset(bio_out);
28282839
}
2840+
BIO_free(bio_out);
28292841
}
28302842

28312843
if (crls != NULL) {
2844+
bio_out = BIO_new(BIO_s_mem());
2845+
if (!bio_out) {
2846+
goto clean_exit;
2847+
}
28322848
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
28332849
X509_CRL* crl = sk_X509_CRL_value(crls, i);
28342850

2835-
bio_out = BIO_new(BIO_s_mem());
2836-
if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) {
2851+
if (PEM_write_bio_X509_CRL(bio_out, crl)) {
28372852
BUF_MEM *bio_buf;
28382853
BIO_get_mem_ptr(bio_out, &bio_buf);
28392854
ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
28402855
add_index_zval(zout, i, &zcert);
28412856
}
2842-
BIO_free(bio_out);
2857+
BIO_reset(bio_out);
28432858
}
2859+
BIO_free(bio_out);
28442860
}
28452861

28462862
RETVAL_TRUE;
@@ -3481,33 +3497,43 @@ PHP_FUNCTION(openssl_cms_read)
34813497
}
34823498

34833499
if (certs != NULL) {
3500+
bio_out = BIO_new(BIO_s_mem());
3501+
if (!bio_out) {
3502+
goto clean_exit;
3503+
}
3504+
34843505
for (i = 0; i < sk_X509_num(certs); i++) {
34853506
X509* ca = sk_X509_value(certs, i);
34863507

3487-
bio_out = BIO_new(BIO_s_mem());
3488-
if (bio_out && PEM_write_bio_X509(bio_out, ca)) {
3508+
if (PEM_write_bio_X509(bio_out, ca)) {
34893509
BUF_MEM *bio_buf;
34903510
BIO_get_mem_ptr(bio_out, &bio_buf);
34913511
ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
34923512
add_index_zval(zout, i, &zcert);
34933513
}
3494-
BIO_free(bio_out);
3514+
BIO_reset(bio_out);
34953515
}
3516+
BIO_free(bio_out);
34963517
}
34973518

34983519
if (crls != NULL) {
3520+
bio_out = BIO_new(BIO_s_mem());
3521+
if (!bio_out) {
3522+
goto clean_exit;
3523+
}
3524+
34993525
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
35003526
X509_CRL* crl = sk_X509_CRL_value(crls, i);
35013527

3502-
bio_out = BIO_new(BIO_s_mem());
3503-
if (bio_out && PEM_write_bio_X509_CRL(bio_out, crl)) {
3528+
if (PEM_write_bio_X509_CRL(bio_out, crl)) {
35043529
BUF_MEM *bio_buf;
35053530
BIO_get_mem_ptr(bio_out, &bio_buf);
35063531
ZVAL_STRINGL(&zcert, bio_buf->data, bio_buf->length);
35073532
add_index_zval(zout, i, &zcert);
35083533
}
3509-
BIO_free(bio_out);
3534+
BIO_reset(bio_out);
35103535
}
3536+
BIO_free(bio_out);
35113537
}
35123538

35133539
RETVAL_TRUE;

ext/openssl/openssl_pwhash.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ ZEND_EXTERN_MODULE_GLOBALS(openssl)
5151
static inline zend_result get_options(zend_array *options, uint32_t *memlimit, uint32_t *iterlimit, uint32_t *threads)
5252
{
5353
zval *opt;
54+
zend_long sthreads;
5455

5556
*iterlimit = PHP_OPENSSL_PWHASH_ITERLIMIT;
5657
*memlimit = PHP_OPENSSL_PWHASH_MEMLIMIT;
@@ -76,8 +77,7 @@ static inline zend_result get_options(zend_array *options, uint32_t *memlimit, u
7677
}
7778
*iterlimit = siterlimit;
7879
}
79-
if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && (zval_get_long(opt) != 1)) {
80-
zend_long sthreads = zval_get_long(opt);
80+
if ((opt = zend_hash_str_find(options, "threads", strlen("threads"))) && ((sthreads = zval_get_long(opt)) != 1)) {
8181
if ((sthreads < PHP_OPENSSL_THREADS_MIN) || (sthreads > PHP_OPENSSL_THREADS_MAX)) {
8282
zend_value_error("Invalid number of threads");
8383
return FAILURE;

ext/openssl/xp_ssl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,7 @@ static unsigned char *php_openssl_alpn_protos_parse(unsigned short *outlen, cons
15081508
return NULL;
15091509
}
15101510

1511-
out = emalloc(strlen(in) + 1);
1511+
out = emalloc(len + 1);
15121512

15131513
for (i = 0; i <= len; ++i) {
15141514
if (i == len || in[i] == ',') {

0 commit comments

Comments
 (0)