@@ -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,42 @@ 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 = NULL ;
3589
+ php_error_docref (NULL , E_WARNING , "Cannot init PKCS11 engine" );
3590
+ TMP_CLEAN ;
3591
+ }
3592
+ }
3570
3593
/* it's an X509 file/cert of some kind, and we need to extract the data from that */
3571
3594
if (public_key ) {
3572
- cert = php_openssl_x509_from_str (Z_STR_P (val ));
3595
+ if (engine ) {
3596
+ key = ENGINE_load_public_key (engine , Z_STRVAL_P (val ), NULL , NULL );
3597
+ ENGINE_free (engine );
3598
+ ENGINE_finish (engine );
3599
+ engine = NULL ;
3600
+ }
3601
+ /* val could be a certificate (file, pkcs11:, etc., let's try to extract the key */
3602
+ if (!key )
3603
+ cert = php_openssl_x509_from_str (Z_STR_P (val ));
3573
3604
3574
3605
if (cert ) {
3575
3606
free_cert = 1 ;
3576
- } else {
3607
+ } else if (! key ) {
3577
3608
/* not a X509 certificate, try to retrieve public key */
3578
3609
BIO * in ;
3579
3610
if (filename ) {
0 commit comments