@@ -3550,6 +3550,8 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas
3550
3550
} else if (Z_TYPE_P (val ) == IS_OBJECT && Z_OBJCE_P (val ) == php_openssl_certificate_ce ) {
3551
3551
cert = php_openssl_certificate_from_obj (Z_OBJ_P (val ))-> x509 ;
3552
3552
} else {
3553
+ ENGINE * engine = NULL ;
3554
+
3553
3555
/* force it to be a string and check if it refers to a file */
3554
3556
/* passing non string values leaks, object uses toString, it returns NULL
3555
3557
* See bug38255.phpt
@@ -3567,13 +3569,43 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas
3567
3569
TMP_CLEAN ;
3568
3570
}
3569
3571
}
3572
+ if (Z_STRLEN_P (val ) > 7 && memcmp (Z_STRVAL_P (val ), "pkcs11:" , sizeof ("pkcs11:" ) - 1 ) == 0 ) {
3573
+ char * verbose = NULL ;
3574
+ engine = ENGINE_by_id ("pkcs11" );
3575
+ if (engine == NULL ) {
3576
+ php_error_docref (NULL , E_WARNING , "Cannot load PKCS11 engine" );
3577
+ TMP_CLEAN ;
3578
+ }
3579
+ verbose = getenv ("OPENSSL_ENGINE_VERBOSE" );
3580
+ if (verbose ) {
3581
+ if (!ENGINE_ctrl_cmd_string (engine , "VERBOSE" , NULL , 0 )) {
3582
+ ENGINE_free (engine );
3583
+ TMP_CLEAN ;
3584
+ }
3585
+ }
3586
+ if (!ENGINE_init (engine )) {
3587
+ ENGINE_free (engine );
3588
+ ENGINE_finish (engine );
3589
+ engine = NULL ;
3590
+ php_error_docref (NULL , E_WARNING , "Cannot init PKCS11 engine" );
3591
+ TMP_CLEAN ;
3592
+ }
3593
+ }
3570
3594
/* it's an X509 file/cert of some kind, and we need to extract the data from that */
3571
3595
if (public_key ) {
3572
- cert = php_openssl_x509_from_str (Z_STR_P (val ));
3596
+ if (engine ) {
3597
+ key = ENGINE_load_public_key (engine , Z_STRVAL_P (val ), NULL , NULL );
3598
+ ENGINE_free (engine );
3599
+ ENGINE_finish (engine );
3600
+ engine = NULL ;
3601
+ }
3602
+ /* val could be a certificate (file, pkcs11:, etc., let's try to extract the key */
3603
+ if (!key )
3604
+ cert = php_openssl_x509_from_str (Z_STR_P (val ));
3573
3605
3574
3606
if (cert ) {
3575
3607
free_cert = 1 ;
3576
- } else {
3608
+ } else if (! key ) {
3577
3609
/* not a X509 certificate, try to retrieve public key */
3578
3610
BIO * in ;
3579
3611
if (filename ) {
0 commit comments