Fix memory leak in hash functions

This commit is contained in:
Vladimir Dubrovin 2026-05-08 12:10:08 +03:00
parent 45c3b89484
commit c104203765
4 changed files with 41 additions and 29 deletions

View File

@ -9,7 +9,6 @@
#ifdef WITH_SSL #ifdef WITH_SSL
#include <openssl/evp.h> #include <openssl/evp.h>
#ifndef WITHMAIN #ifndef WITHMAIN
/* MD5 needed for $1$ crypt */
#endif #endif
#endif #endif
#include <string.h> #include <string.h>
@ -28,8 +27,9 @@ static unsigned char itoa64[] =
#if defined(WITH_SSL) #if defined(WITH_SSL)
EVP_MD *md4 = NULL; EVP_MD *md4_hash = NULL;
EVP_MD *md5 = NULL; EVP_MD *md5_hash = NULL;
EVP_MD *blake2_hash = NULL;
#endif #endif
void void
@ -51,7 +51,7 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
unsigned int len=sizeof(szUnicodePass); unsigned int len=sizeof(szUnicodePass);
unsigned int i; unsigned int i;
if(md4 == NULL) return NULL; if(md4_hash == NULL) return NULL;
/* /*
* NT passwords are unicode. Convert plain text password * NT passwords are unicode. Convert plain text password
@ -67,7 +67,7 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
/* Encrypt Unicode password to a 16-byte MD4 hash */ /* Encrypt Unicode password to a 16-byte MD4 hash */
ctx = EVP_MD_CTX_new(); ctx = EVP_MD_CTX_new();
if(!ctx) return NULL; if(!ctx) return NULL;
if(!EVP_DigestInit_ex(ctx, md4, NULL)){ if(!EVP_DigestInit_ex(ctx, md4_hash, NULL)){
EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx);
return NULL; return NULL;
} }
@ -100,7 +100,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
unsigned int len; unsigned int len;
int pl, i; int pl, i;
if(md5 == NULL) { if(md5_hash == NULL) {
*passwd = 0; *passwd = 0;
return NULL; return NULL;
} }
@ -114,7 +114,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
*passwd = 0; *passwd = 0;
return NULL; return NULL;
} }
EVP_DigestInit_ex(ctx, md5, NULL); EVP_DigestInit_ex(ctx, md5_hash, NULL);
/* The password first, since that is what is most unknown */ /* The password first, since that is what is most unknown */
EVP_DigestUpdate(ctx,pw,strlen((char *)pw)); EVP_DigestUpdate(ctx,pw,strlen((char *)pw));
@ -161,7 +161,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
*/ */
for(i=0;i<1000;i++) { for(i=0;i<1000;i++) {
EVP_MD_CTX_reset(ctx1); EVP_MD_CTX_reset(ctx1);
EVP_DigestInit_ex(ctx1, md5, NULL); EVP_DigestInit_ex(ctx1, md5_hash, NULL);
if(i & 1) if(i & 1)
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw)); EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
else else
@ -231,7 +231,8 @@ OSSL_LIB_CTX *library_ctx = NULL;
#endif #endif
#include <stdio.h> #include <stdio.h>
int main(int argc, char* argv[]){ int main(int argc, char* argv[]){
unsigned char buf[1024]; unsigned char buf1[128];
unsigned char buf2[128];
unsigned i; unsigned i;
if(argc < 2 || argc > 3) { if(argc < 2 || argc > 3) {
fprintf(stderr, "usage: \n" fprintf(stderr, "usage: \n"
@ -259,18 +260,22 @@ int main(int argc, char* argv[]){
library_ctx = OSSL_LIB_CTX_new(); library_ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER_load(library_ctx, "legacy"); OSSL_PROVIDER_load(library_ctx, "legacy");
OSSL_PROVIDER_load(library_ctx, "default"); OSSL_PROVIDER_load(library_ctx, "default");
md4 = EVP_MD_fetch(library_ctx, "MD4", NULL); md4_hash = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4 == NULL) { if (md4_hash == NULL) {
fprintf(stderr, "Error fetching MD4\n"); fprintf(stderr, "Error fetching MD4\n");
} }
md5 = EVP_MD_fetch(library_ctx, "MD5", NULL); md5_hash = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5 == NULL) { if (md5_hash == NULL) {
fprintf(stderr, "Error fetching MD5\n"); fprintf(stderr, "Error fetching MD5\n");
} }
blake2_hash = EVP_blake2b512();
if (blake2_hash == NULL) {
fprintf(stderr, "Error fetching Blake2\n");
}
#endif #endif
if(argc == 2) { if(argc == 2) {
#ifdef WITH_SSL #ifdef WITH_SSL
{ unsigned char *nt = ntpwdhash(buf, (unsigned char *)argv[1], 1); { unsigned char *nt = ntpwdhash(buf1, (unsigned char *)argv[1], 1);
if(nt) printf("NT:%s\n", nt); } if(nt) printf("NT:%s\n", nt); }
#else #else
fprintf(stderr, "NT crypt not available (compiled without OpenSSL)\n"); fprintf(stderr, "NT crypt not available (compiled without OpenSSL)\n");
@ -280,8 +285,8 @@ int main(int argc, char* argv[]){
unsigned char *cr; unsigned char *cr;
i = (int)strlen((char *)argv[1]); i = (int)strlen((char *)argv[1]);
if (i > 64) argv[1][64] = 0; if (i > 64) argv[1][64] = 0;
sprintf((char *)buf, "$3$%s$", argv[1]); sprintf((char *)buf1, "$3$%.64s$", argv[1]);
cr = mycrypt((unsigned char *)argv[2], buf, buf+256); cr = mycrypt((unsigned char *)argv[2], buf1, buf2);
if(cr) printf("CR:%s\n", cr); if(cr) printf("CR:%s\n", cr);
} }
return 0; return 0;

View File

@ -183,8 +183,8 @@ char *strNcpy(char *dest, const char *src, int n)
return dest; return dest;
} }
extern EVP_MD *md4; extern EVP_MD *md4_hash;
extern EVP_MD *md5; extern EVP_MD *md5_hash;
void md5_calc(unsigned char *output, unsigned char *input, void md5_calc(unsigned char *output, unsigned char *input,
@ -192,7 +192,7 @@ void md5_calc(unsigned char *output, unsigned char *input,
{ {
EVP_MD_CTX *ctx = EVP_MD_CTX_new(); EVP_MD_CTX *ctx = EVP_MD_CTX_new();
unsigned int len = 0; unsigned int len = 0;
EVP_DigestInit_ex(ctx, md5, NULL); EVP_DigestInit_ex(ctx, md5_hash, NULL);
EVP_DigestUpdate(ctx, input, inlen); EVP_DigestUpdate(ctx, input, inlen);
EVP_DigestFinal_ex(ctx, output, &len); EVP_DigestFinal_ex(ctx, output, &len);
EVP_MD_CTX_free(ctx); EVP_MD_CTX_free(ctx);

View File

@ -24,6 +24,7 @@
*/ */
typedef EVP_MD_CTX *blake2b_state; typedef EVP_MD_CTX *blake2b_state;
extern EVP_MD *blake2_hash;
static int blake2b_init(blake2b_state *S, size_t outlen) { static int blake2b_init(blake2b_state *S, size_t outlen) {
*S = EVP_MD_CTX_new(); *S = EVP_MD_CTX_new();
@ -35,10 +36,10 @@ static int blake2b_init(blake2b_state *S, size_t outlen) {
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &sz); params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &sz);
params[1] = OSSL_PARAM_construct_end(); params[1] = OSSL_PARAM_construct_end();
if (!EVP_DigestInit_ex2(*S, EVP_blake2b512(), params)) { if (!EVP_DigestInit_ex2(*S, blake2_hash, params)) {
#else #else
(void)outlen; (void)outlen;
if (!EVP_DigestInit_ex(*S, EVP_blake2b512(), NULL)) { if (!EVP_DigestInit_ex(*S, blake2_hash, NULL)) {
#endif #endif
EVP_MD_CTX_free(*S); EVP_MD_CTX_free(*S);
*S = NULL; *S = NULL;

View File

@ -279,8 +279,9 @@ int ssl_file_init = 0;
int ssl_init_done = 0; int ssl_init_done = 0;
OSSL_LIB_CTX *library_ctx = NULL; OSSL_LIB_CTX *library_ctx = NULL;
extern EVP_MD *md4; extern EVP_MD *md4_hash;
extern EVP_MD *md5; extern EVP_MD *md5_hash;
extern EVP_MD *blake2_hash;
void ssl_init() void ssl_init()
@ -296,13 +297,18 @@ void ssl_init()
library_ctx = OSSL_LIB_CTX_new(); library_ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER_load(library_ctx, "legacy"); OSSL_PROVIDER_load(library_ctx, "legacy");
OSSL_PROVIDER_load(library_ctx, "default"); OSSL_PROVIDER_load(library_ctx, "default");
md4 = EVP_MD_fetch(library_ctx, "MD4", NULL); md4_hash = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4 == NULL) { if (md4_hash == NULL) {
printf("Error fetching MD4\n"); fprintf(stderr, "Error fetching MD4\n");
} }
md5 = EVP_MD_fetch(library_ctx, "MD5", NULL); md5_hash = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5 == NULL) { if (md5_hash == NULL) {
printf("Error fetching MD5\n"); fprintf(stderr, "Error fetching MD5\n");
} }
blake2_hash = EVP_blake2b512();
if (blake2_hash == NULL) {
fprintf(stderr, "Error fetching Blake2\n");
}
} }
} }