Skip to content

openssl_sign() stub probably should not contain array type in private_key #16275

@piotrekkr

Description

@piotrekkr

Description

The following stub code:

/**
* @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): bool {}

suggest that $private_key can be array somhow but it is not documented anywhere beside stub.
Also, I'm not fluent in C but there seems to be no array handling in function

php-src/ext/openssl/openssl.c

Lines 7107 to 7174 in 2501cad

PHP_FUNCTION(openssl_sign)
{
zval *key, *signature;
EVP_PKEY *pkey;
zend_string *sigbuf = NULL;
char * data;
size_t data_len;
EVP_MD_CTX *md_ctx;
zend_string *method_str = NULL;
zend_long method_long = OPENSSL_ALGO_SHA1;
const EVP_MD *mdtype;
bool can_default_digest = ZEND_THREEWAY_COMPARE(PHP_OPENSSL_API_VERSION, 0x30000) >= 0;
ZEND_PARSE_PARAMETERS_START(3, 4)
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)
ZEND_PARSE_PARAMETERS_END();
pkey = php_openssl_pkey_from_zval(key, 0, "", 0, 3);
if (pkey == NULL) {
if (!EG(exception)) {
php_error_docref(NULL, E_WARNING, "Supplied key param cannot be coerced into a private key");
}
RETURN_FALSE;
}
if (method_str) {
mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str));
} else {
mdtype = php_openssl_get_evp_md_from_algo(method_long);
}
if (!mdtype && (!can_default_digest || method_long != 0)) {
php_error_docref(NULL, E_WARNING, "Unknown digest algorithm");
RETURN_FALSE;
}
md_ctx = EVP_MD_CTX_create();
size_t siglen;
#if PHP_OPENSSL_API_VERSION >= 0x10100
if (md_ctx != NULL &&
EVP_DigestSignInit(md_ctx, NULL, mdtype, NULL, pkey) &&
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)) {
#else
if (md_ctx != NULL &&
EVP_SignInit(md_ctx, mdtype) &&
EVP_SignUpdate(md_ctx, data, data_len) &&
(siglen = EVP_PKEY_size(pkey)) &&
(sigbuf = zend_string_alloc(siglen, 0)) != NULL &&
EVP_SignFinal(md_ctx, (unsigned char*)ZSTR_VAL(sigbuf), (unsigned int*)&siglen, pkey)) {
#endif
ZSTR_VAL(sigbuf)[siglen] = '\0';
ZSTR_LEN(sigbuf) = siglen;
ZEND_TRY_ASSIGN_REF_NEW_STR(signature, sigbuf);
RETVAL_TRUE;
} else {
php_openssl_store_errors();
efree(sigbuf);
RETVAL_FALSE;
}
EVP_MD_CTX_destroy(md_ctx);
EVP_PKEY_free(pkey);
}
/* }}} */

There is a (high) possibility that I'm wrong and stub is correct and just docs are to be updated and array type documented.

Can you check what is correct?

I also added an issue in for the docs. I've got reply that docs is based on stub files from php-src, so better to check first here.

Thank you.

PHP Version

PHP 8.3.11

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions