Skip to content

Commit 4951d71

Browse files
committed
Add openssl_cipher_key_length function
This function works in exactly the same way as openssl_cipher_iv_length but for a key length. This is especially useful to make sure that the right key length is provided to openssl_encrypt and openssl_decrypt.
1 parent aa702c5 commit 4951d71

8 files changed

+118
-11
lines changed

ext/openssl/openssl.c

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7600,44 +7600,76 @@ PHP_FUNCTION(openssl_decrypt)
76007600
}
76017601
/* }}} */
76027602

7603-
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method)
7603+
static inline const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *method)
76047604
{
76057605
const EVP_CIPHER *cipher_type;
76067606

76077607
cipher_type = EVP_get_cipherbyname(method);
76087608
if (!cipher_type) {
76097609
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
7610-
return -1;
7610+
return NULL;
76117611
}
76127612

7613-
return EVP_CIPHER_iv_length(cipher_type);
7613+
return cipher_type;
7614+
}
7615+
7616+
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method)
7617+
{
7618+
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
7619+
7620+
return cipher_type == NULL ? -1 : EVP_CIPHER_iv_length(cipher_type);
76147621
}
76157622

7616-
/* {{{ */
76177623
PHP_FUNCTION(openssl_cipher_iv_length)
76187624
{
7619-
char *method;
7620-
size_t method_len;
7625+
zend_string *method;
76217626
zend_long ret;
76227627

7623-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &method, &method_len) == FAILURE) {
7628+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &method) == FAILURE) {
76247629
RETURN_THROWS();
76257630
}
76267631

7627-
if (!method_len) {
7632+
if (ZSTR_LEN(method) == 0) {
76287633
zend_argument_value_error(1, "cannot be empty");
76297634
RETURN_THROWS();
76307635
}
76317636

76327637
/* Warning is emitted in php_openssl_cipher_iv_length */
7633-
if ((ret = php_openssl_cipher_iv_length(method)) == -1) {
7638+
if ((ret = php_openssl_cipher_iv_length(ZSTR_VAL(method))) == -1) {
76347639
RETURN_FALSE;
76357640
}
76367641

76377642
RETURN_LONG(ret);
76387643
}
7639-
/* }}} */
76407644

7645+
PHP_OPENSSL_API zend_long php_openssl_cipher_key_length(const char *method)
7646+
{
7647+
const EVP_CIPHER *cipher_type = php_openssl_get_evp_cipher_by_name(method);
7648+
7649+
return cipher_type == NULL ? -1 : EVP_CIPHER_key_length(cipher_type);
7650+
}
7651+
7652+
PHP_FUNCTION(openssl_cipher_key_length)
7653+
{
7654+
zend_string *method;
7655+
zend_long ret;
7656+
7657+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &method) == FAILURE) {
7658+
RETURN_THROWS();
7659+
}
7660+
7661+
if (ZSTR_LEN(method) == 0) {
7662+
zend_argument_value_error(1, "cannot be empty");
7663+
RETURN_THROWS();
7664+
}
7665+
7666+
/* Warning is emitted in php_openssl_cipher_key_length */
7667+
if ((ret = php_openssl_cipher_key_length(ZSTR_VAL(method))) == -1) {
7668+
RETURN_FALSE;
7669+
}
7670+
7671+
RETURN_LONG(ret);
7672+
}
76417673

76427674
PHP_OPENSSL_API zend_string* php_openssl_random_pseudo_bytes(zend_long buffer_length)
76437675
{

ext/openssl/openssl.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ function openssl_decrypt(string $data, string $cipher_algo, #[\SensitiveParamete
610610

611611
function openssl_cipher_iv_length(string $cipher_algo): int|false {}
612612

613+
function openssl_cipher_key_length(string $cipher_algo): int|false {}
614+
613615
function openssl_dh_compute_key(string $public_key, #[\SensitiveParameter] OpenSSLAsymmetricKey $private_key): string|false {}
614616

615617
/**

ext/openssl/openssl_arginfo.h

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/openssl/php_openssl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ php_stream_transport_factory_func php_openssl_ssl_socket_factory;
9393
void php_openssl_store_errors(void);
9494

9595
PHP_OPENSSL_API zend_long php_openssl_cipher_iv_length(const char *method);
96+
PHP_OPENSSL_API zend_long php_openssl_cipher_key_length(const char *method);
9697
PHP_OPENSSL_API zend_string* php_openssl_random_pseudo_bytes(zend_long length);
9798
PHP_OPENSSL_API zend_string* php_openssl_encrypt(
9899
const char *data, size_t data_len,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
openssl_cipher_iv_length() basic test
3+
--EXTENSIONS--
4+
openssl
5+
--FILE--
6+
<?php
7+
8+
var_dump(openssl_cipher_iv_length('AES-128-CBC'));
9+
10+
?>
11+
--EXPECT--
12+
int(16)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
openssl_cipher_iv_length() error test
3+
--EXTENSIONS--
4+
openssl
5+
--FILE--
6+
<?php
7+
8+
var_dump(openssl_cipher_iv_length('unknown'));
9+
10+
try {
11+
var_dump(openssl_cipher_iv_length(''));
12+
} catch (ValueError $e) {
13+
echo $e->getMessage() . "\n";
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
19+
Warning: openssl_cipher_iv_length(): Unknown cipher algorithm in %s on line %d
20+
bool(false)
21+
openssl_cipher_iv_length(): Argument #1 ($cipher_algo) cannot be empty
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
openssl_cipher_key_length() basic test
3+
--EXTENSIONS--
4+
openssl
5+
--FILE--
6+
<?php
7+
8+
var_dump(openssl_cipher_key_length('AES-128-CBC'));
9+
var_dump(openssl_cipher_key_length('AES-256-CBC'));
10+
11+
?>
12+
--EXPECT--
13+
int(16)
14+
int(32)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
openssl_cipher_key_length() error test
3+
--EXTENSIONS--
4+
openssl
5+
--FILE--
6+
<?php
7+
8+
var_dump(openssl_cipher_key_length('unknown'));
9+
10+
try {
11+
var_dump(openssl_cipher_key_length(''));
12+
} catch (ValueError $e) {
13+
echo $e->getMessage() . "\n";
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
19+
Warning: openssl_cipher_key_length(): Unknown cipher algorithm in %s on line %d
20+
bool(false)
21+
openssl_cipher_key_length(): Argument #1 ($cipher_algo) cannot be empty

0 commit comments

Comments
 (0)