[PHP-CVS] svn: /php/php-src/trunk/ext/openssl/ openssl.c tests/011.phpt tests/openssl_decrypt_error.phpt

2010-05-19 Thread Sara Golemon
pollita  Wed, 19 May 2010 20:05:09 +

Revision: http://svn.php.net/viewvc?view=revisionrevision=299508

Log:
Add  parameter to openssl_(en|de)crypt

Changed paths:
U   php/php-src/trunk/ext/openssl/openssl.c
U   php/php-src/trunk/ext/openssl/tests/011.phpt
U   php/php-src/trunk/ext/openssl/tests/openssl_decrypt_error.phpt

Modified: php/php-src/trunk/ext/openssl/openssl.c
===
--- php/php-src/trunk/ext/openssl/openssl.c	2010-05-19 19:34:58 UTC (rev 299507)
+++ php/php-src/trunk/ext/openssl/openssl.c	2010-05-19 20:05:09 UTC (rev 299508)
@@ -99,6 +99,7 @@
 PHP_FUNCTION(openssl_digest);
 PHP_FUNCTION(openssl_encrypt);
 PHP_FUNCTION(openssl_decrypt);
+PHP_FUNCTION(openssl_cipher_iv_length);

 PHP_FUNCTION(openssl_dh_compute_key);
 PHP_FUNCTION(openssl_random_pseudo_bytes);
@@ -347,6 +348,7 @@
 ZEND_ARG_INFO(0, method)
 ZEND_ARG_INFO(0, password)
 ZEND_ARG_INFO(0, raw_output)
+ZEND_ARG_INFO(0, iv)
 ZEND_END_ARG_INFO()

 ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_decrypt, 0, 0, 3)
@@ -354,8 +356,13 @@
 ZEND_ARG_INFO(0, method)
 ZEND_ARG_INFO(0, password)
 ZEND_ARG_INFO(0, raw_input)
+ZEND_ARG_INFO(0, iv)
 ZEND_END_ARG_INFO()

+ZEND_BEGIN_ARG_INFO(arginfo_openssl_cipher_iv_length, 0)
+ZEND_ARG_INFO(0, method)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO(arginfo_openssl_dh_compute_key, 0)
 ZEND_ARG_INFO(0, pub_key)
 ZEND_ARG_INFO(0, dh_key)
@@ -408,6 +415,7 @@
 	PHP_FE(openssl_digest,arginfo_openssl_digest)
 	PHP_FE(openssl_encrypt,arginfo_openssl_encrypt)
 	PHP_FE(openssl_decrypt,arginfo_openssl_decrypt)
+	PHP_FE(openssl_cipher_iv_length,	arginfo_openssl_cipher_iv_length)
 	PHP_FE(openssl_sign,arginfo_openssl_sign)
 	PHP_FE(openssl_verify,arginfo_openssl_verify)
 	PHP_FE(openssl_seal,arginfo_openssl_seal)
@@ -4585,19 +4593,54 @@
 }
 /* }}} */

-/* {{{ proto string openssl_encrypt(string data, string method, string password [, bool raw_output=false])
+static zend_bool php_openssl_validate_iv(char **piv, int *piv_len, int iv_required_len)
+{
+	char *iv_new;
+
+	/* Best case scenario, user behaved */
+	if (*piv_len == iv_required_len) {
+		return 0;
+	}
+
+	iv_new = ecalloc(1, iv_required_len + 1);
+
+	if (*piv_len = 0) {
+		/* BC behavior */
+		*piv_len = iv_required_len;
+		*piv = iv_new;
+		return 1;
+	}
+
+	if (*piv_len  iv_required_len) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, IV passed is only %d bytes long, cipher expects an IV of precisely %d bytes, padding with \\0, *piv_len, iv_required_len);
+		memcpy(iv_new, *piv, *piv_len);
+		*piv_len = iv_required_len;
+		*piv = iv_new;
+		return 1;
+	}
+
+	php_error_docref(NULL TSRMLS_CC, E_WARNING, IV passed is %d bytes long which is longer than the %d expected by selected cipher, truncating, *piv_len, iv_required_len);
+	memcpy(iv_new, *piv, iv_required_len);
+	*piv_len = iv_required_len;
+	*piv = iv_new;
+	return 1;
+
+}
+
+/* {{{ proto string openssl_encrypt(string data, string method, string password [, bool raw_output=false [, 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;
-	char *data, *method, *password;
-	int data_len, method_len, password_len;
+	char *data, *method, *password, *iv = ;
+	int data_len, method_len, password_len, iv_len = 0;
 	const EVP_CIPHER *cipher_type;
 	EVP_CIPHER_CTX cipher_ctx;
-	int i, outlen, keylen, ivlen;
-	unsigned char *outbuf, *key, *iv;
+	int i, outlen, keylen;
+	unsigned char *outbuf, *key;
+	zend_bool free_iv;

-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, sss|b, data, data_len, method, method_len, password, password_len, raw_output) == FAILURE) {
+	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) {
 		return;
 	}
 	cipher_type = EVP_get_cipherbyname(method);
@@ -4615,14 +4658,15 @@
 		key = (unsigned char*)password;
 	}

-	ivlen = EVP_CIPHER_iv_length(cipher_type);
-	iv = emalloc(ivlen);
-	memset(iv, 0, ivlen);
+	if (iv_len = 0) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, Using an empty Initialization Vector (iv) is potentially insecure and not recommended);
+	}
+	free_iv = php_openssl_validate_iv(iv, iv_len, EVP_CIPHER_iv_length(cipher_type));

 	outlen = data_len + EVP_CIPHER_block_size(cipher_type);
 	outbuf = emalloc(outlen + 1);

-	EVP_EncryptInit(cipher_ctx, cipher_type, key, iv);
+	EVP_EncryptInit(cipher_ctx, cipher_type, key, (unsigned char *)iv);
 	EVP_EncryptUpdate(cipher_ctx, outbuf, i, (unsigned char *)data, data_len);
 	outlen = i;
 	if (EVP_EncryptFinal(cipher_ctx, (unsigned char *)outbuf + i, i)) {
@@ -4645,25 +4689,28 @@
 	if (key != (unsigned char*)password) {
 		efree(key);
 	}
-	efree(iv);
+	if (free_iv) {
+		efree(iv);
+	}
 }
 /* }}} */

-/* {{{ proto string 

Re: [PHP-CVS] svn: /php/php-src/trunk/ext/openssl/ openssl.c tests/011.phpt tests/openssl_decrypt_error.phpt

2010-05-19 Thread Pierre Joye
hi,

Little notice for the doc team, please see the respective on internals
for the details about this new parameter.

Cheers,

On Wed, May 19, 2010 at 10:05 PM, Sara Golemon poll...@php.net wrote:
 pollita                                  Wed, 19 May 2010 20:05:09 +

 Revision: http://svn.php.net/viewvc?view=revisionrevision=299508

 Log:
 Add  parameter to openssl_(en|de)crypt

 Changed paths:
    U   php/php-src/trunk/ext/openssl/openssl.c
    U   php/php-src/trunk/ext/openssl/tests/011.phpt
    U   php/php-src/trunk/ext/openssl/tests/openssl_decrypt_error.phpt


 --
 PHP CVS Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php




-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php