mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 12:41: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:
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user