1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Check the key and iv length before giving them to OpenSSL in l_encrypt

and l_decrypt. Otherwise, OpenSSL reads unallocated memory:

openssl.encrypt("DES", "key", "iv", "datadatadatadata")

==5691== Invalid read of size 1
==5691==    at 0x412F07D: DES_set_key_unchecked (in /usr/lib/libcrypto.so.0.9.8)
==5691==  Address 0x4bcc415 is 2 bytes after a block of size 19 alloc'd
==5691==    at 0x402598A: malloc (vg_replace_malloc.c:195)
==5691==    by 0x4025A16: realloc (vg_replace_malloc.c:476)
==5691==    by 0x80ED502: luaM_realloc_ (in /home/david/nmap/nmap)
==5691==    by 0x80F134B: luaS_newlstr (in /home/david/nmap/nmap)
==5691==    by 0x80F85FA: luaX_newstring (in /home/david/nmap/nmap)
==5691==    by 0x80F8FF6: llex (in /home/david/nmap/nmap)
==5691==    by 0x80F9861: luaX_next (in /home/david/nmap/nmap)
==5691==    by 0x80EDCAF: testnext (in /home/david/nmap/nmap)
==5691==    by 0x80EF718: explist1 (in /home/david/nmap/nmap)
==5691==    by 0x80EF7C0: funcargs (in /home/david/nmap/nmap)
==5691==    by 0x80EFA1C: primaryexp (in /home/david/nmap/nmap)
==5691==    by 0x80EEE16: subexpr (in /home/david/nmap/nmap)
This commit is contained in:
david
2010-03-15 22:49:09 +00:00
parent 7d1aa1a634
commit 181bb7ca93

View File

@@ -361,22 +361,39 @@ static int l_encrypt(lua_State *L) /** encrypt( string algorithm, string key, st
const EVP_CIPHER * evp_cipher = EVP_get_cipherbyname( algorithm );
if (!evp_cipher) return luaL_error( L, "Unknown cipher algorithm: %s", algorithm );
size_t data_len;
const unsigned char *key = (unsigned char *) luaL_checkstring( L, 2 );
const unsigned char *iv = (unsigned char *) luaL_optstring( L, 3, "" );
size_t key_len, iv_len, data_len;
const unsigned char *key = (unsigned char *) luaL_checklstring( L, 2, &key_len );
const unsigned char *iv = (unsigned char *) luaL_optlstring( L, 3, "", &iv_len );
const unsigned char *data = (unsigned char *) luaL_checklstring( L, 4, &data_len );
int padding = lua_toboolean( L, 5 );
if (iv[0] == '\0')
iv = NULL;
EVP_CIPHER_CTX cipher_ctx;
EVP_CIPHER_CTX_init( &cipher_ctx );
/* First create the cipher context, then set the key length and padding, and
check the iv length. Below we set the key and iv. */
if (!(
EVP_EncryptInit_ex( &cipher_ctx, evp_cipher, NULL, NULL, NULL ) &&
EVP_CIPHER_CTX_set_key_length( &cipher_ctx, key_len ) &&
EVP_CIPHER_CTX_set_padding( &cipher_ctx, padding ))) {
unsigned long e = ERR_get_error();
return luaL_error( L, "OpenSSL error %d in %s: function %s: %s", e, ERR_lib_error_string(e),
ERR_func_error_string(e), ERR_reason_error_string(e));
}
if (iv != NULL && (int) iv_len != EVP_CIPHER_CTX_iv_length( &cipher_ctx )) {
return luaL_error( L, "Length of iv is %d; should be %d",
(int) iv_len, EVP_CIPHER_CTX_iv_length( &cipher_ctx ));
}
int out_len, final_len;
unsigned char * out = (unsigned char *) malloc( data_len + EVP_MAX_BLOCK_LENGTH );
if (!out) return luaL_error( L, "Couldn't allocate memory.");
if (!(
EVP_EncryptInit_ex( &cipher_ctx, evp_cipher, NULL, key, *iv ? iv : NULL ) &&
EVP_CIPHER_CTX_set_padding( &cipher_ctx, padding ) &&
EVP_EncryptInit_ex( &cipher_ctx, evp_cipher, NULL, key, iv ) &&
EVP_EncryptUpdate( &cipher_ctx, out, &out_len, data, data_len ) &&
EVP_EncryptFinal_ex( &cipher_ctx, out + out_len, &final_len ) )) {
EVP_CIPHER_CTX_cleanup( &cipher_ctx );
@@ -400,22 +417,37 @@ static int l_decrypt(lua_State *L) /** decrypt( string algorithm, string key, st
const EVP_CIPHER * evp_cipher = EVP_get_cipherbyname( algorithm );
if (!evp_cipher) return luaL_error( L, "Unknown cipher algorithm: %s", algorithm );
size_t data_len;
const unsigned char *key = (unsigned char *) luaL_checkstring( L, 2 );
const unsigned char *iv = (unsigned char *) luaL_optstring( L, 3, "" );
size_t key_len, iv_len, data_len;
const unsigned char *key = (unsigned char *) luaL_checklstring( L, 2, &key_len );
const unsigned char *iv = (unsigned char *) luaL_optlstring( L, 3, "", &iv_len );
const unsigned char *data = (unsigned char *) luaL_checklstring( L, 4, &data_len );
int padding = lua_toboolean( L, 5 );
if (iv[0] == '\0')
iv = NULL;
EVP_CIPHER_CTX cipher_ctx;
EVP_CIPHER_CTX_init( &cipher_ctx );
if (!(
EVP_DecryptInit_ex( &cipher_ctx, evp_cipher, NULL, NULL, NULL ) &&
EVP_CIPHER_CTX_set_key_length( &cipher_ctx, key_len ) &&
EVP_CIPHER_CTX_set_padding( &cipher_ctx, padding ))) {
unsigned long e = ERR_get_error();
return luaL_error( L, "OpenSSL error %d in %s: function %s: %s", e, ERR_lib_error_string(e),
ERR_func_error_string(e), ERR_reason_error_string(e));
}
if (iv != NULL && (int) iv_len != EVP_CIPHER_CTX_iv_length( &cipher_ctx )) {
return luaL_error( L, "Length of iv is %d; should be %d",
(int) iv_len, EVP_CIPHER_CTX_iv_length( &cipher_ctx ));
}
int out_len, final_len;
unsigned char * out = (unsigned char *) malloc( data_len );
if (!out) return luaL_error( L, "Couldn't allocate memory.");
if (!(
EVP_DecryptInit_ex( &cipher_ctx, evp_cipher, NULL, key, *iv ? iv : NULL ) &&
EVP_CIPHER_CTX_set_padding( &cipher_ctx, padding ) &&
EVP_DecryptInit_ex( &cipher_ctx, evp_cipher, NULL, key, iv ) &&
EVP_DecryptUpdate( &cipher_ctx, out, &out_len, data, data_len ) &&
EVP_DecryptFinal_ex( &cipher_ctx, out + out_len, &final_len ) )) {
EVP_CIPHER_CTX_cleanup( &cipher_ctx );