@@ -3725,6 +3725,29 @@ PHP_FUNCTION(openssl_cms_decrypt)
37253725
37263726/* }}} */
37273727
3728+ /* Helper to set RSA padding and digest for OAEP */
3729+ static int php_openssl_set_rsa_padding_and_digest (EVP_PKEY_CTX * ctx , zend_long padding , const char * digest_algo , const EVP_MD * * pmd )
3730+ {
3731+ if (EVP_PKEY_CTX_set_rsa_padding (ctx , padding ) <= 0 ) {
3732+ return 0 ;
3733+ }
3734+
3735+ if (digest_algo != NULL ) {
3736+ const EVP_MD * md = php_openssl_get_evp_md_by_name (digest_algo );
3737+ if (md == NULL ) {
3738+ php_error_docref (NULL , E_WARNING , "Unknown digest algorithm: %s" , digest_algo );
3739+ return 0 ;
3740+ }
3741+ * pmd = md ;
3742+ if (padding == RSA_PKCS1_OAEP_PADDING ) {
3743+ if (EVP_PKEY_CTX_set_rsa_oaep_md (ctx , md ) <= 0 ) {
3744+ return 0 ;
3745+ }
3746+ }
3747+ }
3748+
3749+ return 1 ;
3750+ }
37283751
37293752/* {{{ Encrypts data with private key */
37303753PHP_FUNCTION (openssl_private_encrypt )
@@ -3780,10 +3803,12 @@ PHP_FUNCTION(openssl_private_decrypt)
37803803{
37813804 zval * key , * crypted ;
37823805 zend_long padding = RSA_PKCS1_PADDING ;
3783- char * data ;
3784- size_t data_len ;
3806+ char * data ;
3807+ char * digest_algo = NULL ;
3808+ size_t data_len , digest_algo_len = 0 ;
3809+ const EVP_MD * md = NULL ;
37853810
3786- if (zend_parse_parameters (ZEND_NUM_ARGS (), "szz|l " , & data , & data_len , & crypted , & key , & padding ) == FAILURE ) {
3811+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "szz|lp! " , & data , & data_len , & crypted , & key , & padding , & digest_algo , & digest_algo_len ) == FAILURE ) {
37873812 RETURN_THROWS ();
37883813 }
37893814
@@ -3798,7 +3823,7 @@ PHP_FUNCTION(openssl_private_decrypt)
37983823 size_t out_len = 0 ;
37993824 EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new (pkey , NULL );
38003825 if (!ctx || EVP_PKEY_decrypt_init (ctx ) <= 0 ||
3801- EVP_PKEY_CTX_set_rsa_padding (ctx , padding ) <= 0 ||
3826+ ! php_openssl_set_rsa_padding_and_digest (ctx , padding , digest_algo , & md ) ||
38023827 EVP_PKEY_decrypt (ctx , NULL , & out_len , (unsigned char * ) data , data_len ) <= 0 ) {
38033828 php_openssl_store_errors ();
38043829 RETVAL_FALSE ;
@@ -3820,6 +3845,7 @@ PHP_FUNCTION(openssl_private_decrypt)
38203845 RETVAL_TRUE ;
38213846
38223847cleanup :
3848+ php_openssl_release_evp_md (md );
38233849 EVP_PKEY_CTX_free (ctx );
38243850 EVP_PKEY_free (pkey );
38253851}
@@ -3831,9 +3857,11 @@ PHP_FUNCTION(openssl_public_encrypt)
38313857 zval * key , * crypted ;
38323858 zend_long padding = RSA_PKCS1_PADDING ;
38333859 char * data ;
3834- size_t data_len ;
3860+ char * digest_algo = NULL ;
3861+ size_t data_len , digest_algo_len = 0 ;
3862+ const EVP_MD * md = NULL ;
38353863
3836- if (zend_parse_parameters (ZEND_NUM_ARGS (), "szz|l " , & data , & data_len , & crypted , & key , & padding ) == FAILURE ) {
3864+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "szz|lp! " , & data , & data_len , & crypted , & key , & padding , & digest_algo , & digest_algo_len ) == FAILURE ) {
38373865 RETURN_THROWS ();
38383866 }
38393867
@@ -3848,7 +3876,7 @@ PHP_FUNCTION(openssl_public_encrypt)
38483876 size_t out_len = 0 ;
38493877 EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new (pkey , NULL );
38503878 if (!ctx || EVP_PKEY_encrypt_init (ctx ) <= 0 ||
3851- EVP_PKEY_CTX_set_rsa_padding (ctx , padding ) <= 0 ||
3879+ ! php_openssl_set_rsa_padding_and_digest (ctx , padding , digest_algo , & md ) ||
38523880 EVP_PKEY_encrypt (ctx , NULL , & out_len , (unsigned char * ) data , data_len ) <= 0 ) {
38533881 php_openssl_store_errors ();
38543882 RETVAL_FALSE ;
@@ -3869,6 +3897,7 @@ PHP_FUNCTION(openssl_public_encrypt)
38693897 RETVAL_TRUE ;
38703898
38713899cleanup :
3900+ php_openssl_release_evp_md (md );
38723901 EVP_PKEY_CTX_free (ctx );
38733902 EVP_PKEY_free (pkey );
38743903}
@@ -3879,7 +3908,7 @@ PHP_FUNCTION(openssl_public_decrypt)
38793908{
38803909 zval * key , * crypted ;
38813910 zend_long padding = RSA_PKCS1_PADDING ;
3882- char * data ;
3911+ char * data ;
38833912 size_t data_len ;
38843913
38853914 if (zend_parse_parameters (ZEND_NUM_ARGS (), "szz|l" , & data , & data_len , & crypted , & key , & padding ) == FAILURE ) {
0 commit comments