]> granicus.if.org Git - php/commitdiff
Allow management of your own padding in openssl_encrypt/decrypt.
authorScott MacVicar <scottmac@php.net>
Fri, 20 May 2011 18:56:13 +0000 (18:56 +0000)
committerScott MacVicar <scottmac@php.net>
Fri, 20 May 2011 18:56:13 +0000 (18:56 +0000)
For using mcrypt / openssl interchangeabley managing your own padding is the only solution.

ext/openssl/openssl.c
ext/openssl/php_openssl.h
ext/openssl/tests/011.phpt
ext/openssl/tests/bug54060.phpt
ext/openssl/tests/bug54061.phpt
ext/openssl/tests/openssl_decrypt_error.phpt

index 784049f626e95b22493629eb3d971e36f5f2a442..4377d2b52e039758517e80c0df3fbcd9e56529c6 100644 (file)
@@ -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)) {
index dc53eb12826b674b66c0f4139a60d811e6a7f594..3b3d1e61a96c01aaa7b05fe4ffca4be0ec6654e5 100644 (file)
@@ -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);
index fdcc5e296a3641a297f3a58eefb8d86dab08fc22..118e952a5107ec0e8d629e76d3c5d8caea0abde3 100644 (file)
@@ -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"
index fe8ca94a5fe59f57ab4d8fbcd8452d76e478d105..88f1f944df9ccf7a0002820f689f033a81907415 100644 (file)
@@ -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--
index cef3944119112f80b43988100502f8707f8fc73a..f1d2e24a289758c73a8878b8bccf89ac808ab055 100644 (file)
@@ -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--
index 233fa0c5bdf7b25c4397c87722fd82d1223964e7..40debbd04f2d3891bec03bc2a19c75377e4cea13 100644 (file)
@@ -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));