Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion ext/openssl/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4026,6 +4026,27 @@ static zend_result php_openssl_setup_rsa_padding(EVP_PKEY_CTX *pctx, EVP_PKEY *p
return SUCCESS;
}

static int php_openssl_setup_rsa_pss_salt_length(EVP_PKEY_CTX *pctx, EVP_PKEY *pkey, zend_long padding, zend_long salt_length)
{
/* Only apply if using PSS padding */
if (padding != RSA_PKCS1_PSS_PADDING) {
return SUCCESS;
}

/* Only apply to RSA keys */
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA && EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA_PSS) {
return SUCCESS;
}

if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, (int)salt_length) <= 0) {
php_openssl_store_errors();
php_error_docref(NULL, E_WARNING, "Could not set RSA-PSS salt length");
return FAILURE;
}

return SUCCESS;
}

/* {{{ Signs data */
PHP_FUNCTION(openssl_sign)
{
Expand All @@ -4039,16 +4060,18 @@ PHP_FUNCTION(openssl_sign)
zend_long method_long = OPENSSL_ALGO_SHA1;
const EVP_MD *mdtype;
zend_long padding = 0;
zend_long salt_length = RSA_PSS_SALTLEN_AUTO;
EVP_PKEY_CTX *pctx;
bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0;

ZEND_PARSE_PARAMETERS_START(3, 5)
ZEND_PARSE_PARAMETERS_START(3, 6)
Z_PARAM_STRING(data, data_len)
Z_PARAM_ZVAL(signature)
Z_PARAM_ZVAL(key)
Z_PARAM_OPTIONAL
Z_PARAM_STR_OR_LONG(method_str, method_long)
Z_PARAM_LONG(padding)
Z_PARAM_LONG(salt_length)
ZEND_PARSE_PARAMETERS_END();

pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3);
Expand All @@ -4069,12 +4092,14 @@ PHP_FUNCTION(openssl_sign)
php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
RETURN_FALSE;
}
PHP_OPENSSL_CHECK_LONG_TO_INT(salt_length, salt_length, 6);

md_ctx = EVP_MD_CTX_create();
size_t siglen;
if (md_ctx != NULL &&
EVP_DigestSignInit(md_ctx, &pctx, mdtype, NULL, pkey) &&
php_openssl_setup_rsa_padding(pctx, pkey, padding) == SUCCESS &&
php_openssl_setup_rsa_pss_salt_length(pctx, pkey, padding, salt_length) == SUCCESS &&
EVP_DigestSign(md_ctx, NULL, &siglen, (unsigned char*)data, data_len) &&
(sigbuf = zend_string_alloc(siglen, 0)) != NULL &&
EVP_DigestSign(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), &siglen, (unsigned char*)data, data_len)) {
Expand Down
18 changes: 17 additions & 1 deletion ext/openssl/openssl.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,22 @@
*/
const OPENSSL_PKCS1_PSS_PADDING = UNKNOWN;

/**
* @var int
* @cvalue RSA_PSS_SALTLEN_DIGEST
*/
const OPENSSL_RSA_PSS_SALTLEN_DIGEST = UNKNOWN;
/**
* @var int
* @cvalue RSA_PSS_SALTLEN_AUTO
*/
const OPENSSL_RSA_PSS_SALTLEN_AUTO = UNKNOWN;
/**
* @var int
* @cvalue RSA_PSS_SALTLEN_MAX
*/
const OPENSSL_RSA_PSS_SALTLEN_MAX = UNKNOWN;

/* Informational stream wrapper constants */

/**
Expand Down Expand Up @@ -619,7 +635,7 @@ function openssl_error_string(): string|false {}
* @param string $signature
* @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key
*/
function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): bool {}
function openssl_sign(string $data, &$signature, #[\SensitiveParameter] $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0, int $salt_length = OPENSSL_RSA_PSS_SALTLEN_AUTO): bool {}

/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */
function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1, int $padding = 0): int|false {}
Expand Down
6 changes: 5 additions & 1 deletion ext/openssl/openssl_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion ext/openssl/tests/openssl_sign_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ openssl
$data = "Testing openssl_sign()";
$privkey = "file://" . __DIR__ . "/private_rsa_1024.key";
$wrong = "wrong";

var_dump(openssl_sign($data, $sign1, $privkey, OPENSSL_ALGO_SHA256));
var_dump(bin2hex($sign1));
var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256));
Expand All @@ -17,6 +16,10 @@ var_dump(strlen($sign1));
var_dump(openssl_sign($data, $sign2, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING));
var_dump(strlen($sign2));
var_dump($sign1 === $sign2);
var_dump(openssl_sign($data, $sign3, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, OPENSSL_RSA_PSS_SALTLEN_DIGEST));
var_dump(strlen($sign3));
var_dump(openssl_sign($data, $sign4, $privkey, OPENSSL_ALGO_SHA256, OPENSSL_PKCS1_PSS_PADDING, 32));
var_dump(strlen($sign4));
var_dump(openssl_sign($data, $sign, $wrong));
?>
--EXPECTF--
Expand All @@ -29,6 +32,10 @@ int(128)
bool(true)
int(128)
bool(false)
bool(true)
int(128)
bool(true)
int(128)

Warning: openssl_sign(): Supplied key param cannot be coerced into a private key in %s on line %d
bool(false)