mirror of
https://github.com/nmap/nmap.git
synced 2026-05-13 08:46:45 +00:00
Ensure crypto CTX objects are freed. Fixes #2550
This commit is contained in:
parent
e4fd4bd2fe
commit
7332939768
3 changed files with 79 additions and 86 deletions
|
|
@ -162,6 +162,7 @@ static char *make_nonce(const struct timeval *tv)
|
|||
enhex(hash_hex, hashbuf, hash_size);
|
||||
|
||||
strbuf_sprintf(&buf, &size, &offset, "%s-%s", time_buf, hash_hex);
|
||||
EVP_MD_CTX_free(md5);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
|
@ -216,6 +217,7 @@ static void make_response(char buf[EVP_MAX_MD_SIZE * 2 + 1],
|
|||
EVP_DigestFinal_ex(md5, hashbuf, &hash_size);
|
||||
|
||||
enhex(buf, hashbuf, hash_size);
|
||||
EVP_MD_CTX_free(md5);
|
||||
}
|
||||
|
||||
/* Extract the issuance time from a nonce (without checking other aspects of
|
||||
|
|
|
|||
|
|
@ -72,17 +72,10 @@
|
|||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined LIBRESSL_VERSION_NUMBER
|
||||
#define HAVE_OPAQUE_EVP_PKEY 1
|
||||
#define FUNC_EVP_MD_CTX_init EVP_MD_CTX_reset
|
||||
#define FUNC_EVP_MD_CTX_cleanup EVP_MD_CTX_reset
|
||||
#define FUNC_EVP_CIPHER_CTX_init EVP_CIPHER_CTX_reset
|
||||
#define FUNC_EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_reset
|
||||
#define PASS_EVP_CTX(ctx) (ctx)
|
||||
#else
|
||||
#define FUNC_EVP_MD_CTX_init EVP_MD_CTX_init
|
||||
#define FUNC_EVP_MD_CTX_cleanup EVP_MD_CTX_cleanup
|
||||
#define FUNC_EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init
|
||||
#define FUNC_EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup
|
||||
#define PASS_EVP_CTX(ctx) (&(ctx))
|
||||
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
||||
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_cleanup
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
|
@ -136,22 +129,23 @@ int Crypto::aes128_cbc_encrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
|
|||
#if HAVE_OPAQUE_EVP_PKEY
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
#else
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX stack_ctx;
|
||||
EVP_CIPHER_CTX *ctx = &stack_ctx;
|
||||
EVP_CIPHER_CTX_init(ctx);
|
||||
#endif
|
||||
FUNC_EVP_CIPHER_CTX_init(PASS_EVP_CTX(ctx));
|
||||
EVP_CIPHER_CTX_set_padding(PASS_EVP_CTX(ctx), 0);
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
int result=OP_SUCCESS;
|
||||
if( EVP_EncryptInit(PASS_EVP_CTX(ctx), EVP_aes_128_cbc(), key, iv)==0 ){
|
||||
if( EVP_EncryptInit(ctx, EVP_aes_128_cbc(), key, iv)==0 ){
|
||||
nping_print(DBG_4, "EVP_EncryptInit() failed");
|
||||
result=OP_FAILURE;
|
||||
}else if( EVP_EncryptUpdate(PASS_EVP_CTX(ctx), dst_buff, &flen, inbuff, (int)inlen)==0 ){
|
||||
}else if( EVP_EncryptUpdate(ctx, dst_buff, &flen, inbuff, (int)inlen)==0 ){
|
||||
nping_print(DBG_4, "EVP_EncryptUpdate() failed");
|
||||
result=OP_FAILURE;
|
||||
}else if( EVP_EncryptFinal(PASS_EVP_CTX(ctx), dst_buff+flen, &flen2)==0 ){
|
||||
}else if( EVP_EncryptFinal(ctx, dst_buff+flen, &flen2)==0 ){
|
||||
nping_print(DBG_4, "EVP_EncryptFinal() failed");
|
||||
result=OP_FAILURE;
|
||||
}
|
||||
FUNC_EVP_CIPHER_CTX_cleanup(PASS_EVP_CTX(ctx));
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -175,18 +169,19 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
|
|||
#if HAVE_OPAQUE_EVP_PKEY
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
#else
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX stack_ctx;
|
||||
EVP_CIPHER_CTX *ctx = &stack_ctx;
|
||||
EVP_CIPHER_CTX_init(ctx);
|
||||
#endif
|
||||
FUNC_EVP_CIPHER_CTX_init(PASS_EVP_CTX(ctx));
|
||||
EVP_CIPHER_CTX_set_padding(PASS_EVP_CTX(ctx), 0);
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
int result=OP_SUCCESS;
|
||||
if( EVP_DecryptInit(PASS_EVP_CTX(ctx), EVP_aes_128_cbc(), key, iv)==0 ){
|
||||
if( EVP_DecryptInit(ctx, EVP_aes_128_cbc(), key, iv)==0 ){
|
||||
nping_print(DBG_4, "EVP_DecryptInit() failed");
|
||||
result=OP_FAILURE;
|
||||
}else if( EVP_DecryptUpdate(PASS_EVP_CTX(ctx), dst_buff, &flen1, inbuff, (int)inlen)==0 ){
|
||||
}else if( EVP_DecryptUpdate(ctx, dst_buff, &flen1, inbuff, (int)inlen)==0 ){
|
||||
nping_print(DBG_4, "EVP_DecryptUpdate() failed");
|
||||
result=OP_FAILURE;
|
||||
}else if( EVP_DecryptFinal(PASS_EVP_CTX(ctx), dst_buff+flen1, &flen2)==0 ){
|
||||
}else if( EVP_DecryptFinal(ctx, dst_buff+flen1, &flen2)==0 ){
|
||||
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
|
||||
ERR_error_string(ERR_peek_last_error(), NULL));
|
||||
/* We do not return OP_FAILURE in this case because the
|
||||
|
|
@ -215,7 +210,7 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
|
|||
//ERR_free_strings();
|
||||
//ERR_pop_to_mark();
|
||||
}
|
||||
FUNC_EVP_CIPHER_CTX_cleanup(PASS_EVP_CTX(ctx));
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -252,33 +247,28 @@ u8 *Crypto::deriveKey(const u8 *from, size_t fromlen, size_t *final_len){
|
|||
static u8 hash[MAX(SHA256_HASH_LEN, EVP_MAX_MD_SIZE)];
|
||||
static u8 next[MAX(SHA256_HASH_LEN, EVP_MAX_MD_SIZE)];
|
||||
unsigned int lastlen;
|
||||
#if HAVE_OPAQUE_EVP_PKEY
|
||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
||||
#else
|
||||
EVP_MD_CTX ctx;
|
||||
#endif
|
||||
FUNC_EVP_MD_CTX_init(PASS_EVP_CTX(ctx));
|
||||
|
||||
if( EVP_MD_size(EVP_sha256()) != SHA256_HASH_LEN )
|
||||
nping_fatal(QT_2, "OpenSSL is broken. SHA256 len is %d\n", EVP_MD_size(EVP_sha256()) );
|
||||
|
||||
/* Compute the SHA256 hash of the supplied buffer */
|
||||
EVP_DigestInit(PASS_EVP_CTX(ctx), EVP_sha256());
|
||||
EVP_DigestUpdate(PASS_EVP_CTX(ctx), from, fromlen);
|
||||
EVP_DigestFinal(PASS_EVP_CTX(ctx), hash, &lastlen);
|
||||
EVP_DigestInit(ctx, EVP_sha256());
|
||||
EVP_DigestUpdate(ctx, from, fromlen);
|
||||
EVP_DigestFinal(ctx, hash, &lastlen);
|
||||
|
||||
/* Now compute the 1000th hash of that hash */
|
||||
for(int i=0; i<TIMES_KEY_DERIVATION; i++){
|
||||
EVP_MD_CTX_init(PASS_EVP_CTX(ctx));
|
||||
EVP_DigestInit(PASS_EVP_CTX(ctx), EVP_sha256());
|
||||
EVP_DigestUpdate(PASS_EVP_CTX(ctx), hash, SHA256_HASH_LEN);
|
||||
EVP_DigestFinal(PASS_EVP_CTX(ctx), next, &lastlen);
|
||||
EVP_MD_CTX_init(ctx);
|
||||
EVP_DigestInit(ctx, EVP_sha256());
|
||||
EVP_DigestUpdate(ctx, hash, SHA256_HASH_LEN);
|
||||
EVP_DigestFinal(ctx, next, &lastlen);
|
||||
memcpy(hash, next, SHA256_HASH_LEN);
|
||||
}
|
||||
if(final_len!=NULL)
|
||||
*final_len=SHA256_HASH_LEN;
|
||||
|
||||
FUNC_EVP_MD_CTX_cleanup(PASS_EVP_CTX(ctx));
|
||||
EVP_MD_CTX_free(ctx);
|
||||
return hash;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -15,20 +15,13 @@
|
|||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined LIBRESSL_VERSION_NUMBER
|
||||
#define HAVE_OPAQUE_STRUCTS 1
|
||||
#define FUNC_EVP_MD_CTX_init EVP_MD_CTX_reset
|
||||
#define FUNC_EVP_MD_CTX_cleanup EVP_MD_CTX_reset
|
||||
#define FUNC_EVP_CIPHER_CTX_init EVP_CIPHER_CTX_reset
|
||||
#define FUNC_EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_reset
|
||||
#define PASS_EVP_CTX(ctx) (ctx)
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
# include <openssl/provider.h>
|
||||
#endif
|
||||
#else
|
||||
#define FUNC_EVP_MD_CTX_init EVP_MD_CTX_init
|
||||
#define FUNC_EVP_MD_CTX_cleanup EVP_MD_CTX_cleanup
|
||||
#define FUNC_EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init
|
||||
#define FUNC_EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup
|
||||
#define PASS_EVP_CTX(ctx) (&(ctx))
|
||||
#define EVP_MD_CTX_new EVP_MD_CTX_create
|
||||
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||
#define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_cleanup
|
||||
#endif
|
||||
|
||||
#include "nse_lua.h"
|
||||
|
|
@ -282,25 +275,23 @@ static int l_digest(lua_State *L) /** digest(string algorithm, string messag
|
|||
const unsigned char *msg = (unsigned char *) luaL_checklstring( L, 2, &msg_len );
|
||||
unsigned char digest[EVP_MAX_MD_SIZE];
|
||||
const EVP_MD * evp_md;
|
||||
#if HAVE_OPAQUE_STRUCTS
|
||||
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
|
||||
#else
|
||||
EVP_MD_CTX mdctx;
|
||||
#endif
|
||||
EVP_MD_CTX *mdctx = NULL;
|
||||
|
||||
evp_md = EVP_get_digestbyname( algorithm );
|
||||
|
||||
if (!evp_md) return luaL_error( L, "Unknown digest algorithm: %s", algorithm );
|
||||
|
||||
FUNC_EVP_MD_CTX_init(PASS_EVP_CTX(mdctx));
|
||||
mdctx = EVP_MD_CTX_new();
|
||||
if (!mdctx) return NSE_SSL_LUA_ERR(L);
|
||||
|
||||
if (!(
|
||||
EVP_DigestInit_ex( PASS_EVP_CTX(mdctx), evp_md, NULL ) &&
|
||||
EVP_DigestUpdate( PASS_EVP_CTX(mdctx), msg, msg_len ) &&
|
||||
EVP_DigestFinal_ex( PASS_EVP_CTX(mdctx), digest, &digest_len ))) {
|
||||
FUNC_EVP_MD_CTX_cleanup( PASS_EVP_CTX(mdctx) );
|
||||
EVP_DigestInit_ex( mdctx, evp_md, NULL ) &&
|
||||
EVP_DigestUpdate( mdctx, msg, msg_len ) &&
|
||||
EVP_DigestFinal_ex( mdctx, digest, &digest_len ))) {
|
||||
EVP_MD_CTX_free( mdctx );
|
||||
return NSE_SSL_LUA_ERR(L);
|
||||
}
|
||||
FUNC_EVP_MD_CTX_cleanup( PASS_EVP_CTX(mdctx) );
|
||||
EVP_MD_CTX_free( mdctx );
|
||||
|
||||
lua_pushlstring( L, (char *) digest, digest_len );
|
||||
return 1;
|
||||
|
|
@ -393,41 +384,46 @@ static int l_encrypt(lua_State *L) /** encrypt( string algorithm, string key, st
|
|||
#if HAVE_OPAQUE_STRUCTS
|
||||
EVP_CIPHER_CTX *cipher_ctx = EVP_CIPHER_CTX_new();
|
||||
#else
|
||||
EVP_CIPHER_CTX cipher_ctx;
|
||||
EVP_CIPHER_CTX stack_ctx;
|
||||
EVP_CIPHER_CTX *cipher_ctx = &stack_ctx;
|
||||
EVP_CIPHER_CTX_init( cipher_ctx );
|
||||
#endif
|
||||
|
||||
FUNC_EVP_CIPHER_CTX_init( PASS_EVP_CTX(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( PASS_EVP_CTX(cipher_ctx), evp_cipher, NULL, NULL, NULL ) &&
|
||||
EVP_CIPHER_CTX_set_key_length( PASS_EVP_CTX(cipher_ctx), key_len ) &&
|
||||
EVP_CIPHER_CTX_set_padding( PASS_EVP_CTX(cipher_ctx), padding ))) {
|
||||
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 ))) {
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
return NSE_SSL_LUA_ERR(L);
|
||||
}
|
||||
|
||||
if (iv != NULL && (int) iv_len != EVP_CIPHER_CTX_iv_length( PASS_EVP_CTX(cipher_ctx) )) {
|
||||
if (iv != NULL && (int) iv_len != EVP_CIPHER_CTX_iv_length( cipher_ctx )) {
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
return luaL_error( L, "Length of iv is %d; should be %d",
|
||||
(int) iv_len, EVP_CIPHER_CTX_iv_length( PASS_EVP_CTX(cipher_ctx) ));
|
||||
(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 (!out) {
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
return luaL_error( L, "Couldn't allocate memory.");
|
||||
}
|
||||
|
||||
if (!(
|
||||
EVP_EncryptInit_ex( PASS_EVP_CTX(cipher_ctx), NULL, NULL, key, iv ) &&
|
||||
EVP_EncryptUpdate( PASS_EVP_CTX(cipher_ctx), out, &out_len, data, data_len ) &&
|
||||
EVP_EncryptFinal_ex( PASS_EVP_CTX(cipher_ctx), out + out_len, &final_len ) )) {
|
||||
FUNC_EVP_CIPHER_CTX_cleanup( PASS_EVP_CTX(cipher_ctx) );
|
||||
EVP_EncryptInit_ex( cipher_ctx, NULL, 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_free(cipher_ctx);
|
||||
free( out );
|
||||
return NSE_SSL_LUA_ERR(L);
|
||||
}
|
||||
|
||||
lua_pushlstring( L, (char *) out, out_len + final_len );
|
||||
|
||||
FUNC_EVP_CIPHER_CTX_cleanup( PASS_EVP_CTX(cipher_ctx) );
|
||||
EVP_CIPHER_CTX_free( cipher_ctx );
|
||||
free( out );
|
||||
|
||||
return 1;
|
||||
|
|
@ -450,39 +446,44 @@ static int l_decrypt(lua_State *L) /** decrypt( string algorithm, string key, st
|
|||
#if HAVE_OPAQUE_STRUCTS
|
||||
EVP_CIPHER_CTX *cipher_ctx = EVP_CIPHER_CTX_new();
|
||||
#else
|
||||
EVP_CIPHER_CTX cipher_ctx;
|
||||
EVP_CIPHER_CTX stack_ctx;
|
||||
EVP_CIPHER_CTX *cipher_ctx = &stack_ctx;
|
||||
EVP_CIPHER_CTX_init( cipher_ctx );
|
||||
#endif
|
||||
|
||||
FUNC_EVP_CIPHER_CTX_init( PASS_EVP_CTX(cipher_ctx) );
|
||||
|
||||
if (!(
|
||||
EVP_DecryptInit_ex( PASS_EVP_CTX(cipher_ctx), evp_cipher, NULL, NULL, NULL ) &&
|
||||
EVP_CIPHER_CTX_set_key_length( PASS_EVP_CTX(cipher_ctx), key_len ) &&
|
||||
EVP_CIPHER_CTX_set_padding( PASS_EVP_CTX(cipher_ctx), padding ))) {
|
||||
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 ))) {
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
return NSE_SSL_LUA_ERR(L);
|
||||
}
|
||||
|
||||
if (iv != NULL && (int) iv_len != EVP_CIPHER_CTX_iv_length( PASS_EVP_CTX(cipher_ctx) )) {
|
||||
if (iv != NULL && (int) iv_len != EVP_CIPHER_CTX_iv_length( cipher_ctx )) {
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
return luaL_error( L, "Length of iv is %d; should be %d",
|
||||
(int) iv_len, EVP_CIPHER_CTX_iv_length( PASS_EVP_CTX(cipher_ctx) ));
|
||||
(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 (!out) {
|
||||
EVP_CIPHER_CTX_free(cipher_ctx);
|
||||
return luaL_error( L, "Couldn't allocate memory.");
|
||||
}
|
||||
|
||||
if (!(
|
||||
EVP_DecryptInit_ex( PASS_EVP_CTX(cipher_ctx), NULL, NULL, key, iv ) &&
|
||||
EVP_DecryptUpdate( PASS_EVP_CTX(cipher_ctx), out, &out_len, data, data_len ) &&
|
||||
EVP_DecryptFinal_ex( PASS_EVP_CTX(cipher_ctx), out + out_len, &final_len ) )) {
|
||||
FUNC_EVP_CIPHER_CTX_cleanup( PASS_EVP_CTX(cipher_ctx) );
|
||||
EVP_DecryptInit_ex( cipher_ctx, NULL, 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_free( cipher_ctx );
|
||||
free( out );
|
||||
return NSE_SSL_LUA_ERR(L);
|
||||
}
|
||||
|
||||
lua_pushlstring( L, (char *) out, out_len + final_len );
|
||||
|
||||
FUNC_EVP_CIPHER_CTX_cleanup( PASS_EVP_CTX(cipher_ctx) );
|
||||
EVP_CIPHER_CTX_free( cipher_ctx );
|
||||
free( out );
|
||||
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue