From: Scott MacVicar Date: Fri, 20 May 2011 18:56:13 +0000 (+0000) Subject: Allow management of your own padding in openssl_encrypt/decrypt. X-Git-Tag: php-5.5.0alpha1~2061 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e7ae3b2d0e942b816e3836025456544d6288ac3;p=php Allow management of your own padding in openssl_encrypt/decrypt. For using mcrypt / openssl interchangeabley managing your own padding is the only solution. --- diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 784049f626..4377d2b52e 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -350,7 +350,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_encrypt, 0, 0, 3) ZEND_ARG_INFO(0, data) ZEND_ARG_INFO(0, method) ZEND_ARG_INFO(0, password) - ZEND_ARG_INFO(0, raw_output) + ZEND_ARG_INFO(0, options) ZEND_ARG_INFO(0, iv) ZEND_END_ARG_INFO() @@ -358,7 +358,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_decrypt, 0, 0, 3) ZEND_ARG_INFO(0, data) ZEND_ARG_INFO(0, method) ZEND_ARG_INFO(0, password) - ZEND_ARG_INFO(0, raw_input) + ZEND_ARG_INFO(0, options) ZEND_ARG_INFO(0, iv) ZEND_END_ARG_INFO() @@ -1089,6 +1089,9 @@ PHP_MINIT_FUNCTION(openssl) REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_EC", OPENSSL_KEYTYPE_EC, CONST_CS|CONST_PERSISTENT); #endif + REGISTER_LONG_CONSTANT("OPENSSL_RAW_DATA", OPENSSL_RAW_DATA, CONST_CS|CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("OPENSSL_ZERO_PADDING", OPENSSL_ZERO_PADDING, CONST_CS|CONST_PERSISTENT); + #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) /* SNI support included in OpenSSL >= 0.9.8j */ 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 } -/* {{{ proto string openssl_encrypt(string data, string method, string password [, bool raw_output=false [, string $iv='']]) +/* {{{ proto string openssl_encrypt(string data, string method, string password [, long options=0 [, string $iv='']]) Encrypts given data with given method and key, returns raw or base64 encoded string */ PHP_FUNCTION(openssl_encrypt) { - zend_bool raw_output = 0; + long options = 0; char *data, *method, *password, *iv = ""; int data_len, method_len, password_len, iv_len = 0, max_iv_len; const EVP_CIPHER *cipher_type; @@ -4692,7 +4695,7 @@ PHP_FUNCTION(openssl_encrypt) unsigned char *outbuf, *key; zend_bool free_iv; - 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) { + 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) { return; } cipher_type = EVP_get_cipherbyname(method); @@ -4720,11 +4723,14 @@ PHP_FUNCTION(openssl_encrypt) outbuf = emalloc(outlen + 1); EVP_EncryptInit(&cipher_ctx, cipher_type, key, (unsigned char *)iv); + if (options & OPENSSL_ZERO_PADDING) { + EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0); + } EVP_EncryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len); outlen = i; if (EVP_EncryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) { outlen += i; - if (raw_output) { + if (options & OPENSSL_RAW_DATA) { outbuf[outlen] = '\0'; RETVAL_STRINGL((char *)outbuf, outlen, 0); } else { @@ -4749,11 +4755,11 @@ PHP_FUNCTION(openssl_encrypt) } /* }}} */ -/* {{{ proto string openssl_decrypt(string data, string method, string password [, bool raw_input=false [, string $iv = '']]) +/* {{{ proto string openssl_decrypt(string data, string method, string password [, long options=0 [, string $iv = '']]) Takes raw or base64 encoded string and dectupt it using given method and key */ PHP_FUNCTION(openssl_decrypt) { - zend_bool raw_input = 0; + long options = 0; char *data, *method, *password, *iv = ""; int data_len, method_len, password_len, iv_len = 0; const EVP_CIPHER *cipher_type; @@ -4764,7 +4770,7 @@ PHP_FUNCTION(openssl_decrypt) char *base64_str = NULL; zend_bool free_iv; - 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) { + 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) { return; } @@ -4779,7 +4785,7 @@ PHP_FUNCTION(openssl_decrypt) RETURN_FALSE; } - if (!raw_input) { + if (!(options & OPENSSL_RAW_DATA)) { base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len); data_len = base64_str_len; data = base64_str; @@ -4800,6 +4806,9 @@ PHP_FUNCTION(openssl_decrypt) outbuf = emalloc(outlen + 1); EVP_DecryptInit(&cipher_ctx, cipher_type, key, (unsigned char *)iv); + if (options & OPENSSL_ZERO_PADDING) { + EVP_CIPHER_CTX_set_padding(&cipher_ctx, 0); + } EVP_DecryptUpdate(&cipher_ctx, outbuf, &i, (unsigned char *)data, data_len); outlen = i; if (EVP_DecryptFinal(&cipher_ctx, (unsigned char *)outbuf + i, &i)) { diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index dc53eb1282..3b3d1e61a9 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -26,6 +26,9 @@ extern zend_module_entry openssl_module_entry; #define phpext_openssl_ptr &openssl_module_entry +#define OPENSSL_RAW_DATA 1 +#define OPENSSL_ZERO_PADDING 2 + php_stream_transport_factory_func php_openssl_ssl_socket_factory; PHP_MINIT_FUNCTION(openssl); diff --git a/ext/openssl/tests/011.phpt b/ext/openssl/tests/011.phpt index fdcc5e296a..118e952a51 100644 --- a/ext/openssl/tests/011.phpt +++ b/ext/openssl/tests/011.phpt @@ -13,14 +13,19 @@ $iv = ''; srand(time() + ((microtime(true) * 1000000) % 1000000)); while(strlen($iv) < $ivlen) $iv .= chr(rand(0,255)); -$encrypted = openssl_encrypt($data, $method, $password, false, $iv); -$output = openssl_decrypt($encrypted, $method, $password, false, $iv); +$encrypted = openssl_encrypt($data, $method, $password, 0, $iv); +$output = openssl_decrypt($encrypted, $method, $password, 0, $iv); var_dump($output); -$encrypted = openssl_encrypt($data, $method, $password, true, $iv); -$output = openssl_decrypt($encrypted, $method, $password, true, $iv); +$encrypted = openssl_encrypt($data, $method, $password, OPENSSL_RAW_DATA, $iv); +$output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA, $iv); var_dump($output); +// if we want to manage our own padding +$padded_data = $data . str_repeat(' ', 16 - (strlen($data) % 16)); +$encrypted = openssl_encrypt($padded_data, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv); +$output = openssl_decrypt($encrypted, $method, $password, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $iv); +var_dump(rtrim($output)); ?> --EXPECT-- string(45) "openssl_encrypt() and openssl_decrypt() tests" string(45) "openssl_encrypt() and openssl_decrypt() tests" - +string(45) "openssl_encrypt() and openssl_decrypt() tests" diff --git a/ext/openssl/tests/bug54060.phpt b/ext/openssl/tests/bug54060.phpt index fe8ca94a5f..88f1f944df 100644 --- a/ext/openssl/tests/bug54060.phpt +++ b/ext/openssl/tests/bug54060.phpt @@ -10,7 +10,7 @@ r7-89437 r892374 r894372 r894 7289r7 f frwerfh i iurf iuryw uyrfouiwy ruy 972439 8478942 yrhfjkdhls"; $pass = "r23498rui324hjbnkj"; -openssl_encrypt($data, 'des3', $pass, false, '1qazxsw2'); +openssl_encrypt($data, 'des3', $pass, 0, '1qazxsw2'); echo "Done"; ?> --EXPECT-- diff --git a/ext/openssl/tests/bug54061.phpt b/ext/openssl/tests/bug54061.phpt index cef3944119..f1d2e24a28 100644 --- a/ext/openssl/tests/bug54061.phpt +++ b/ext/openssl/tests/bug54061.phpt @@ -9,8 +9,8 @@ r7-89437 r892374 r894372 r894 7289r7 f frwerfh i iurf iuryw uyrfouiwy ruy 972439 8478942 yrhfjkdhls"; $pass = "r23498rui324hjbnkj"; -$cr = openssl_encrypt($data, 'des3', $pass, false, '1qazxsw2'); -$dcr = openssl_decrypt($cr, 'des3', $pass, false, '1qazxsw2'); +$cr = openssl_encrypt($data, 'des3', $pass, 0, '1qazxsw2'); +$dcr = openssl_decrypt($cr, 'des3', $pass, 0, '1qazxsw2'); echo "Done"; ?> --EXPECT-- diff --git a/ext/openssl/tests/openssl_decrypt_error.phpt b/ext/openssl/tests/openssl_decrypt_error.phpt index 233fa0c5bd..40debbd04f 100644 --- a/ext/openssl/tests/openssl_decrypt_error.phpt +++ b/ext/openssl/tests/openssl_decrypt_error.phpt @@ -12,7 +12,7 @@ $iv = str_repeat("\0", openssl_cipher_iv_length($method)); $encrypted = openssl_encrypt($data, $method, $password); var_dump($encrypted); /* Not passing $iv should be the same as all-NULL iv, but with a warning */ -var_dump(openssl_encrypt($data, $method, $password, false, $iv)); +var_dump(openssl_encrypt($data, $method, $password, 0, $iv)); var_dump(openssl_decrypt($encrypted, $method, $wrong)); var_dump(openssl_decrypt($encrypted, $wrong, $password)); var_dump(openssl_decrypt($wrong, $method, $password));