summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Zelenka <bukka@php.net>2015-08-18 20:17:04 +0100
committerJakub Zelenka <bukka@php.net>2015-08-18 20:17:04 +0100
commit6a201b3651b4885f0b5d79f8b7fe06a9c604cf2e (patch)
tree5e196519975bb6bf32f4a850f761bbeb7e335cc0
parent618c327a56b03449324cdaa0d630ea710aea22fd (diff)
downloadphp-git-6a201b3651b4885f0b5d79f8b7fe06a9c604cf2e.tar.gz
Use macros for openssl overflow checks
It reduces code duplications
-rw-r--r--ext/openssl/openssl.c103
1 files changed, 40 insertions, 63 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 1e03ce7164..2876bae76e 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -534,6 +534,16 @@ zend_module_entry openssl_module_entry = {
ZEND_GET_MODULE(openssl)
#endif
+/* overflow checks */
+#define PHP_OPENSSL_CHECK_OVERFLOW_EX(_var, _name, _max) \
+ do { \
+ if (_max < _var) { \
+ php_error_docref(NULL, E_WARNING, #_name" is too long"); \
+ RETURN_FALSE; \
+ } \
+ } while(0)
+#define PHP_OPENSSL_CHECK_OVERFLOW(_var, _name) PHP_OPENSSL_CHECK_OVERFLOW_EX(_var, _name, INT_MAX)
+
static int le_key;
static int le_x509;
static int le_csr;
@@ -4011,22 +4021,11 @@ PHP_FUNCTION(openssl_pbkdf2)
if (key_length <= 0) {
RETURN_FALSE;
}
- if (INT_MAX < key_length) {
- php_error_docref(NULL, E_WARNING, "key_length is too long");
- RETURN_FALSE;
- }
- if (INT_MAX < iterations) {
- php_error_docref(NULL, E_WARNING, "iterations is too long");
- RETURN_FALSE;
- }
- if (INT_MAX < password_len) {
- php_error_docref(NULL, E_WARNING, "password_len is too long");
- RETURN_FALSE;
- }
- if (INT_MAX < salt_len) {
- php_error_docref(NULL, E_WARNING, "salt_len is too long");
- RETURN_FALSE;
- }
+
+ PHP_OPENSSL_CHECK_OVERFLOW(key_length, key);
+ PHP_OPENSSL_CHECK_OVERFLOW(iterations, iterations);
+ PHP_OPENSSL_CHECK_OVERFLOW(password_len, password);
+ PHP_OPENSSL_CHECK_OVERFLOW(salt_len, salt);
if (method_len) {
digest = EVP_get_digestbyname(method);
@@ -4497,11 +4496,10 @@ PHP_FUNCTION(openssl_private_encrypt)
if (pkey == NULL) {
php_error_docref(NULL, E_WARNING, "key param is not a valid private key");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
cryptedlen = EVP_PKEY_size(pkey);
cryptedbuf = zend_string_alloc(cryptedlen, 0);
@@ -4558,11 +4556,10 @@ PHP_FUNCTION(openssl_private_decrypt)
if (pkey == NULL) {
php_error_docref(NULL, E_WARNING, "key parameter is not a valid private key");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
cryptedlen = EVP_PKEY_size(pkey);
crypttemp = emalloc(cryptedlen + 1);
@@ -4625,11 +4622,10 @@ PHP_FUNCTION(openssl_public_encrypt)
if (pkey == NULL) {
php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
cryptedlen = EVP_PKEY_size(pkey);
cryptedbuf = zend_string_alloc(cryptedlen, 0);
@@ -4687,11 +4683,10 @@ PHP_FUNCTION(openssl_public_decrypt)
if (pkey == NULL) {
php_error_docref(NULL, E_WARNING, "key parameter is not a valid public key");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
cryptedlen = EVP_PKEY_size(pkey);
crypttemp = emalloc(cryptedlen + 1);
@@ -4838,10 +4833,8 @@ PHP_FUNCTION(openssl_verify)
return;
}
- if (UINT_MAX < signature_len) {
- php_error_docref(NULL, E_WARNING, "signature is too long");
- RETURN_FALSE;
- }
+ PHP_OPENSSL_CHECK_OVERFLOW_EX(signature_len, signature, UINT_MAX);
+
if (method == NULL || Z_TYPE_P(method) == IS_LONG) {
if (method != NULL) {
signature_algo = Z_LVAL_P(method);
@@ -4901,11 +4894,10 @@ PHP_FUNCTION(openssl_seal)
if (!nkeys) {
php_error_docref(NULL, E_WARNING, "Fourth argument to openssl_seal() must be a non-empty array");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
if (method) {
cipher = EVP_get_cipherbyname(method);
if (!cipher) {
@@ -5033,14 +5025,11 @@ PHP_FUNCTION(openssl_open)
if (pkey == NULL) {
php_error_docref(NULL, E_WARNING, "unable to coerce parameter 4 into a private key");
RETURN_FALSE;
- } else if (INT_MAX < ekey_len) {
- php_error_docref(NULL, E_WARNING, "ekey is too long");
- RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(ekey_len, ekey);
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
if (method) {
cipher = EVP_get_cipherbyname(method);
if (!cipher) {
@@ -5223,11 +5212,10 @@ PHP_FUNCTION(openssl_encrypt)
if (!cipher_type) {
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
keylen = EVP_CIPHER_key_length(cipher_type);
if (keylen > password_len) {
key = emalloc(keylen);
@@ -5248,10 +5236,7 @@ PHP_FUNCTION(openssl_encrypt)
EVP_EncryptInit(&cipher_ctx, cipher_type, NULL, NULL);
if (password_len > keylen) {
- if (INT_MAX < password_len) {
- php_error_docref(NULL, E_WARNING, "password is too long");
- RETURN_FALSE;
- }
+ PHP_OPENSSL_CHECK_OVERFLOW(password_len, password);
EVP_CIPHER_CTX_set_key_length(&cipher_ctx, (int)password_len);
}
EVP_EncryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
@@ -5311,11 +5296,10 @@ PHP_FUNCTION(openssl_decrypt)
if (!method_len) {
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
RETURN_FALSE;
- } else if (INT_MAX < data_len) {
- php_error_docref(NULL, E_WARNING, "data is too long");
- RETURN_FALSE;
}
+ PHP_OPENSSL_CHECK_OVERFLOW(data_len, data);
+
cipher_type = EVP_get_cipherbyname(method);
if (!cipher_type) {
php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm");
@@ -5348,10 +5332,7 @@ PHP_FUNCTION(openssl_decrypt)
EVP_DecryptInit(&cipher_ctx, cipher_type, NULL, NULL);
if (password_len > keylen) {
- if (INT_MAX < password_len) {
- php_error_docref(NULL, E_WARNING, "password is too long");
- RETURN_FALSE;
- }
+ PHP_OPENSSL_CHECK_OVERFLOW(password_len, password);
EVP_CIPHER_CTX_set_key_length(&cipher_ctx, (int)password_len);
}
EVP_DecryptInit_ex(&cipher_ctx, NULL, NULL, key, (unsigned char *)iv);
@@ -5431,10 +5412,7 @@ PHP_FUNCTION(openssl_dh_compute_key)
RETURN_FALSE;
}
- if (INT_MAX < pub_len) {
- php_error_docref(NULL, E_WARNING, "pub_key is too long");
- RETURN_FALSE;
- }
+ PHP_OPENSSL_CHECK_OVERFLOW(pub_len, pub_key);
pub = BN_bin2bn((unsigned char*)pub_str, (int)pub_len, NULL);
data = zend_string_alloc(DH_size(pkey->pkey.dh), 0);
@@ -5486,10 +5464,9 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
RETURN_FALSE;
}
#else
- if (INT_MAX < buffer_length) {
- php_error_docref(NULL, E_WARNING, "length is too long");
- RETURN_FALSE;
- }
+
+ PHP_OPENSSL_CHECK_OVERFLOW(buffer_length, length);
+
if (RAND_bytes((unsigned char*)ZSTR_VAL(buffer), (int)buffer_length) <= 0) {
zend_string_release(buffer);
if (zstrong_result_returned) {