Skip to content

Commit 30f19bd

Browse files
author
Scott MacVicar
committed
Allow management of your own padding in openssl_encrypt/decrypt.
For using mcrypt / openssl interchangeabley managing your own padding is the only solution.
1 parent 1101293 commit 30f19bd

File tree

8 files changed

+41
-19
lines changed

8 files changed

+41
-19
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ PHP NEWS
178178
. Added AES support. FR #48632. (yonas dot y at gmail dot com, Pierre)
179179
. Added a "no_ticket" SSL context option to disable the SessionTicket TLS
180180
extension. FR #53447. (Adam)
181+
. Added no padding option to openssl_encrypt()/openssl_decrypt(). (Scott)
181182

182183
- Improved PDO DB-LIB: (Stanley)
183184
. Added nextRowset support.

UPGRADING

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ UPGRADE NOTES - PHP X.Y
174174
just the first matching node.
175175
- All SimpleXMLElement children are now always printed when using var_dump(),
176176
var_export(), and print_r().
177+
- The raw data parameter in openssl_encrypt()/openssl_decrypt() is now an options
178+
integer rather than a boolean. A value of true produces the same behaviour.
177179

178180
===================================
179181
5. Changes made to existing methods
@@ -392,6 +394,8 @@ UPGRADE NOTES - PHP X.Y
392394
- IPV6_MULTICAST_LOOP
393395
- IPPROTO_IP
394396
- IPPROTO_IPV6
397+
- OPENSSL_RAW_DATA
398+
- OPENSSL_ZERO_PADDING
395399

396400
g. New classes
397401

ext/openssl/openssl.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -350,15 +350,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_encrypt, 0, 0, 3)
350350
ZEND_ARG_INFO(0, data)
351351
ZEND_ARG_INFO(0, method)
352352
ZEND_ARG_INFO(0, password)
353-
ZEND_ARG_INFO(0, raw_output)
353+
ZEND_ARG_INFO(0, options)
354354
ZEND_ARG_INFO(0, iv)
355355
ZEND_END_ARG_INFO()
356356

357357
ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_decrypt, 0, 0, 3)
358358
ZEND_ARG_INFO(0, data)
359359
ZEND_ARG_INFO(0, method)
360360
ZEND_ARG_INFO(0, password)
361-
ZEND_ARG_INFO(0, raw_input)
361+
ZEND_ARG_INFO(0, options)
362362
ZEND_ARG_INFO(0, iv)
363363
ZEND_END_ARG_INFO()
364364

@@ -1089,6 +1089,9 @@ PHP_MINIT_FUNCTION(openssl)
10891089
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_CS|CONST_PERSISTENT);
10901090
#endif
10911091

1092+
REGISTER_LONG_CONSTANT("OPENSSL_RAW_DATA", OPENSSL_RAW_DATA, CONST_CS|CONST_PERSISTENT);
1093+
REGISTER_LONG_CONSTANT("OPENSSL_ZERO_PADDING", OPENSSL_ZERO_PADDING, CONST_CS|CONST_PERSISTENT);
1094+
10921095
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
10931096
/* SNI support included in OpenSSL >= 0.9.8j */
10941097
REGISTER_LONG_CONSTANT("OPENSSL_TLSEXT_SERVER_NAME", 1, CONST_CS|CONST_PERSISTENT);
@@ -4679,11 +4682,11 @@ static zend_bool php_openssl_validate_iv(char **piv, int *piv_len, int iv_requir
46794682

46804683
}
46814684

4682-
/* {{{ proto string openssl_encrypt(string data, string method, string password [, bool raw_output=false [, string $iv='']])
4685+
/* {{{ proto string openssl_encrypt(string data, string method, string password [, long options=0 [, string $iv='']])
46834686
Encrypts given data with given method and key, returns raw or base64 encoded string */
46844687
PHP_FUNCTION(openssl_encrypt)
46854688
{
4686-
zend_bool raw_output = 0;
4689+
long options = 0;
46874690
char *data, *method, *password, *iv = "";
46884691
int data_len, method_len, password_len, iv_len = 0, max_iv_len;
46894692
const EVP_CIPHER *cipher_type;
@@ -4692,7 +4695,7 @@ PHP_FUNCTION(openssl_encrypt)
46924695
unsigned char *outbuf, *key;
46934696
zend_bool free_iv;
46944697

4695-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|bs", &data, &data_len, &method, &method_len, &password, &password_len, &raw_output, &iv, &iv_len) == FAILURE) {
4698+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
46964699
return;
46974700
}
46984701
cipher_type = EVP_get_cipherbyname(method);
@@ -4720,11 +4723,14 @@ PHP_FUNCTION(openssl_encrypt)
47204723
outbuf = emalloc(outlen + 1);
47214724

47224725
EVP_EncryptInit(&cipher_ctx, cipher_type, key, (unsigned char *)iv);
4726+
if (options & OPENSSL_ZERO_PADDING) {
4727+
EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
4728+
}
47234729
EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
47244730
outlen = i;
47254731
if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {
47264732
outlen += i;
4727-
if (raw_output) {
4733+
if (options & OPENSSL_RAW_DATA) {
47284734
outbuf[outlen] = '\0';
47294735
RETVAL_STRINGL((char *)outbuf, outlen, 0);
47304736
} else {
@@ -4749,11 +4755,11 @@ PHP_FUNCTION(openssl_encrypt)
47494755
}
47504756
/* }}} */
47514757

4752-
/* {{{ proto string openssl_decrypt(string data, string method, string password [, bool raw_input=false [, string $iv = '']])
4758+
/* {{{ proto string openssl_decrypt(string data, string method, string password [, long options=0 [, string $iv = '']])
47534759
Takes raw or base64 encoded string and dectupt it using given method and key */
47544760
PHP_FUNCTION(openssl_decrypt)
47554761
{
4756-
zend_bool raw_input = 0;
4762+
long options = 0;
47574763
char *data, *method, *password, *iv = "";
47584764
int data_len, method_len, password_len, iv_len = 0;
47594765
const EVP_CIPHER *cipher_type;
@@ -4764,7 +4770,7 @@ PHP_FUNCTION(openssl_decrypt)
47644770
char *base64_str = NULL;
47654771
zend_bool free_iv;
47664772

4767-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|bs", &data, &data_len, &method, &method_len, &password, &password_len, &raw_input, &iv, &iv_len) == FAILURE) {
4773+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|ls", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) {
47684774
return;
47694775
}
47704776

@@ -4779,7 +4785,7 @@ PHP_FUNCTION(openssl_decrypt)
47794785
RETURN_FALSE;
47804786
}
47814787

4782-
if (!raw_input) {
4788+
if (!(options & OPENSSL_RAW_DATA)) {
47834789
base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len);
47844790
data_len = base64_str_len;
47854791
data = base64_str;
@@ -4800,6 +4806,9 @@ PHP_FUNCTION(openssl_decrypt)
48004806
outbuf = emalloc(outlen + 1);
48014807

48024808
EVP_DecryptInit(&cipher_ctx, cipher_type, key, (unsigned char *)iv);
4809+
if (options & OPENSSL_ZERO_PADDING) {
4810+
EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0);
4811+
}
48034812
EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len);
48044813
outlen = i;
48054814
if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) {

ext/openssl/php_openssl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
extern zend_module_entry openssl_module_entry;
2727
#define phpext_openssl_ptr &openssl_module_entry
2828

29+
#define OPENSSL_RAW_DATA 1
30+
#define OPENSSL_ZERO_PADDING 2
31+
2932
php_stream_transport_factory_func php_openssl_ssl_socket_factory;
3033

3134
PHP_MINIT_FUNCTION(openssl);

ext/openssl/tests/011.phpt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,19 @@ $iv = '';
1313
srand(time() + ((microtime(true) * 1000000) % 1000000));
1414
while(strlen($iv) < $ivlen) $iv .= chr(rand(0,255));
1515

16-
$encrypted = openssl_encrypt($data, $method, $password, false, $iv);
17-
$output = openssl_decrypt($encrypted, $method, $password, false, $iv);
16+
$encrypted = openssl_encrypt($data, $method, $password, 0, $iv);
17+
$output = openssl_decrypt($encrypted, $method, $password, 0, $iv);
1818
var_dump($output);
19-
$encrypted = openssl_encrypt($data, $method, $password, true, $iv);
20-
$output = openssl_decrypt($encrypted, $method, $password, true, $iv);
19+
$encrypted = openssl_encrypt($data, $method, $password, OPENSSL_RAW_DATA, $iv);
20+
$output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA, $iv);
2121
var_dump($output);
22+
// if we want to manage our own padding
23+
$padded_data = $data . str_repeat(' ', 16 - (strlen($data) % 16));
24+
$encrypted = openssl_encrypt($padded_data, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
25+
$output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv);
26+
var_dump(rtrim($output));
2227
?>
2328
--EXPECT--
2429
string(45) "openssl_encrypt() and openssl_decrypt() tests"
2530
string(45) "openssl_encrypt() and openssl_decrypt() tests"
26-
31+
string(45) "openssl_encrypt() and openssl_decrypt() tests"

ext/openssl/tests/bug54060.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ r7-89437 r892374 r894372 r894 7289r7 f frwerfh i iurf iuryw uyrfouiwy ruy
1010
972439 8478942 yrhfjkdhls";
1111
$pass = "r23498rui324hjbnkj";
1212

13-
openssl_encrypt($data, 'des3', $pass, false, '1qazxsw2');
13+
openssl_encrypt($data, 'des3', $pass, 0, '1qazxsw2');
1414
echo "Done";
1515
?>
1616
--EXPECT--

ext/openssl/tests/bug54061.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ r7-89437 r892374 r894372 r894 7289r7 f frwerfh i iurf iuryw uyrfouiwy ruy
99
972439 8478942 yrhfjkdhls";
1010
$pass = "r23498rui324hjbnkj";
1111

12-
$cr = openssl_encrypt($data, 'des3', $pass, false, '1qazxsw2');
13-
$dcr = openssl_decrypt($cr, 'des3', $pass, false, '1qazxsw2');
12+
$cr = openssl_encrypt($data, 'des3', $pass, 0, '1qazxsw2');
13+
$dcr = openssl_decrypt($cr, 'des3', $pass, 0, '1qazxsw2');
1414
echo "Done";
1515
?>
1616
--EXPECT--

ext/openssl/tests/openssl_decrypt_error.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ $iv = str_repeat("\0", openssl_cipher_iv_length($method));
1212

1313
$encrypted = openssl_encrypt($data, $method, $password);
1414
var_dump($encrypted); /* Not passing $iv should be the same as all-NULL iv, but with a warning */
15-
var_dump(openssl_encrypt($data, $method, $password, false, $iv));
15+
var_dump(openssl_encrypt($data, $method, $password, 0, $iv));
1616
var_dump(openssl_decrypt($encrypted, $method, $wrong));
1717
var_dump(openssl_decrypt($encrypted, $wrong, $password));
1818
var_dump(openssl_decrypt($wrong, $method, $password));

0 commit comments

Comments
 (0)