@@ -3997,6 +3997,30 @@ PHP_FUNCTION(openssl_error_string)
39973997}
39983998/* }}} */
39993999
4000+ static zend_result php_openssl_setup_rsa_padding (EVP_PKEY_CTX * pctx , EVP_PKEY * pkey , zend_long padding )
4001+ {
4002+ int key_type = EVP_PKEY_type (EVP_PKEY_id (pkey ));
4003+
4004+ if (padding != 0 ) { // 0 = default/unspecified
4005+ if (key_type != EVP_PKEY_RSA ) {
4006+ php_error_docref (NULL , E_WARNING , "Padding parameter is only supported for RSA keys" );
4007+ return FAILURE ;
4008+ }
4009+
4010+ if (padding == RSA_PKCS1_PSS_PADDING ) {
4011+ if (EVP_PKEY_CTX_set_rsa_padding (pctx , RSA_PKCS1_PSS_PADDING ) <= 0 ) {
4012+ php_openssl_store_errors ();
4013+ return FAILURE ;
4014+ }
4015+ } else if (padding != RSA_PKCS1_PADDING ) {
4016+ php_error_docref (NULL , E_WARNING , "Unknown padding type" );
4017+ return FAILURE ;
4018+ }
4019+ }
4020+
4021+ return SUCCESS ;
4022+ }
4023+
40004024/* {{{ Signs data */
40014025PHP_FUNCTION (openssl_sign )
40024026{
@@ -4009,14 +4033,17 @@ PHP_FUNCTION(openssl_sign)
40094033 zend_string * method_str = NULL ;
40104034 zend_long method_long = OPENSSL_ALGO_SHA1 ;
40114035 const EVP_MD * mdtype ;
4036+ zend_long padding = 0 ;
4037+ EVP_PKEY_CTX * pctx ;
40124038 bool can_default_digest = ZEND_THREEWAY_COMPARE (PHP_OPENSSL_API_VERSION , 0x30000 ) >= 0 ;
40134039
4014- ZEND_PARSE_PARAMETERS_START (3 , 4 )
4040+ ZEND_PARSE_PARAMETERS_START (3 , 5 )
40154041 Z_PARAM_STRING (data , data_len )
40164042 Z_PARAM_ZVAL (signature )
40174043 Z_PARAM_ZVAL (key )
40184044 Z_PARAM_OPTIONAL
40194045 Z_PARAM_STR_OR_LONG (method_str , method_long )
4046+ Z_PARAM_LONG (padding )
40204047 ZEND_PARSE_PARAMETERS_END ();
40214048
40224049 pkey = php_openssl_pkey_from_zval (key , 0 , "" , 0 , 3 );
@@ -4041,7 +4068,8 @@ PHP_FUNCTION(openssl_sign)
40414068 md_ctx = EVP_MD_CTX_create ();
40424069 size_t siglen ;
40434070 if (md_ctx != NULL &&
4044- EVP_DigestSignInit (md_ctx , NULL , mdtype , NULL , pkey ) &&
4071+ EVP_DigestSignInit (md_ctx , & pctx , mdtype , NULL , pkey ) &&
4072+ php_openssl_setup_rsa_padding (pctx , pkey , padding ) == SUCCESS &&
40454073 EVP_DigestSign (md_ctx , NULL , & siglen , (unsigned char * )data , data_len ) &&
40464074 (sigbuf = zend_string_alloc (siglen , 0 )) != NULL &&
40474075 EVP_DigestSign (md_ctx , (unsigned char * )ZSTR_VAL (sigbuf ), & siglen , (unsigned char * )data , data_len )) {
@@ -4074,14 +4102,17 @@ PHP_FUNCTION(openssl_verify)
40744102 size_t signature_len ;
40754103 zend_string * method_str = NULL ;
40764104 zend_long method_long = OPENSSL_ALGO_SHA1 ;
4105+ zend_long padding = 0 ;
4106+ EVP_PKEY_CTX * pctx ;
40774107 bool can_default_digest = ZEND_THREEWAY_COMPARE (PHP_OPENSSL_API_VERSION , 0x30000 ) >= 0 ;
40784108
4079- ZEND_PARSE_PARAMETERS_START (3 , 4 )
4109+ ZEND_PARSE_PARAMETERS_START (3 , 5 )
40804110 Z_PARAM_STRING (data , data_len )
40814111 Z_PARAM_STRING (signature , signature_len )
40824112 Z_PARAM_ZVAL (key )
40834113 Z_PARAM_OPTIONAL
40844114 Z_PARAM_STR_OR_LONG (method_str , method_long )
4115+ Z_PARAM_LONG (padding )
40854116 ZEND_PARSE_PARAMETERS_END ();
40864117
40874118 PHP_OPENSSL_CHECK_SIZE_T_TO_UINT (signature_len , signature , 2 ) ;
@@ -4106,11 +4137,25 @@ PHP_FUNCTION(openssl_verify)
41064137 }
41074138
41084139 md_ctx = EVP_MD_CTX_create ();
4109- if (md_ctx == NULL ||
4110- !EVP_DigestVerifyInit (md_ctx , NULL , mdtype , NULL , pkey ) ||
4111- (err = EVP_DigestVerify (md_ctx , (unsigned char * )signature , signature_len , (unsigned char * )data , data_len )) < 0 ) {
4140+ if (md_ctx == NULL ) {
41124141 php_openssl_store_errors ();
4142+ err = -1 ;
4143+ goto cleanup ;
41134144 }
4145+
4146+ if (!EVP_DigestVerifyInit (md_ctx , & pctx , mdtype , NULL , pkey ) ||
4147+ php_openssl_setup_rsa_padding (pctx , pkey , padding ) == FAILURE ) {
4148+ php_openssl_store_errors ();
4149+ err = -1 ;
4150+ goto cleanup ;
4151+ }
4152+
4153+ err = EVP_DigestVerify (md_ctx , (unsigned char * )signature , signature_len , (unsigned char * )data , data_len );
4154+ if (err < 0 ) {
4155+ php_openssl_store_errors ();
4156+ }
4157+
4158+ cleanup :
41144159 EVP_MD_CTX_destroy (md_ctx );
41154160 php_openssl_release_evp_md (mdtype );
41164161 EVP_PKEY_free (pkey );
0 commit comments