md5: refactor for standard compliance

- Wrap OpenSSL / wolfSSL MD5 functions instead of taking their function
  addresses during static initialization.

Depending on how curl was built the old way may have used a dllimport
function address during static initialization, which is not standard
compliant, resulting in Visual Studio warning C4232 (nonstandard
extension). Instead the function pointers now point to the wrappers
which call the MD5 functions.

This change only affects OpenSSL and wolfSSL because calls to other SSL
libraries' md5 functions were already wrapped. Also sha256.c already
does this for all SSL libraries.

Ref: https://github.com/curl/curl/pull/8298

Closes https://github.com/curl/curl/pull/8318
This commit is contained in:
Jay Satiro 2022-01-21 17:09:29 -05:00
parent 519b62ccd0
commit 0e5c4f574b

112
lib/md5.c
View File

@ -60,22 +60,22 @@
/* The last #include file should be: */
#include "memdebug.h"
typedef struct md5_ctx MD5_CTX;
typedef struct md5_ctx my_md5_ctx;
static CURLcode MD5_Init(MD5_CTX *ctx)
static CURLcode my_md5_init(my_md5_ctx *ctx)
{
md5_init(ctx);
return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
static void my_md5_update(my_md5_ctx *ctx,
const unsigned char *input,
unsigned int inputLen)
{
md5_update(ctx, inputLen, input);
}
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
{
md5_digest(ctx, 16, digest);
}
@ -93,6 +93,26 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
typedef MD5_CTX my_md5_ctx;
static CURLcode my_md5_init(my_md5_ctx *ctx)
{
(void)MD5_Init(ctx);
return CURLE_OK;
}
static void my_md5_update(my_md5_ctx *ctx,
const unsigned char *input,
unsigned int len)
{
(void)MD5_Update(ctx, input, len);
}
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
{
(void)MD5_Final(digest, ctx);
}
#elif defined(USE_MBEDTLS)
#include <mbedtls/md5.h>
@ -102,9 +122,9 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
/* The last #include file should be: */
#include "memdebug.h"
typedef mbedtls_md5_context MD5_CTX;
typedef mbedtls_md5_context my_md5_ctx;
static CURLcode MD5_Init(MD5_CTX *ctx)
static CURLcode my_md5_init(my_md5_ctx *ctx)
{
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
(void) mbedtls_md5_starts(ctx);
@ -114,9 +134,9 @@ static CURLcode MD5_Init(MD5_CTX *ctx)
return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *data,
unsigned int length)
static void my_md5_update(my_md5_ctx *ctx,
const unsigned char *data,
unsigned int length)
{
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
(void) mbedtls_md5_update(ctx, data, length);
@ -125,7 +145,7 @@ static void MD5_Update(MD5_CTX *ctx,
#endif
}
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
{
#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
(void) mbedtls_md5_finish(ctx, digest);
@ -148,25 +168,25 @@ static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
Declaring the functions as static like this seems to be a bit more
reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
# include <CommonCrypto/CommonDigest.h>
# define MD5_CTX CC_MD5_CTX
# define my_md5_ctx CC_MD5_CTX
#include "curl_memory.h"
/* The last #include file should be: */
#include "memdebug.h"
static CURLcode MD5_Init(MD5_CTX *ctx)
static CURLcode my_md5_init(my_md5_ctx *ctx)
{
CC_MD5_Init(ctx);
return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
static void my_md5_update(my_md5_ctx *ctx,
const unsigned char *input,
unsigned int inputLen)
{
CC_MD5_Update(ctx, input, inputLen);
}
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
{
CC_MD5_Final(digest, ctx);
}
@ -182,9 +202,9 @@ struct md5_ctx {
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
};
typedef struct md5_ctx MD5_CTX;
typedef struct md5_ctx my_md5_ctx;
static CURLcode MD5_Init(MD5_CTX *ctx)
static CURLcode my_md5_init(my_md5_ctx *ctx)
{
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
@ -193,14 +213,14 @@ static CURLcode MD5_Init(MD5_CTX *ctx)
return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
static void my_md5_update(my_md5_ctx *ctx,
const unsigned char *input,
unsigned int inputLen)
{
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
}
static void MD5_Final(unsigned char *digest, MD5_CTX *ctx)
static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
{
unsigned long length = 0;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
@ -268,11 +288,12 @@ struct md5_ctx {
unsigned char buffer[64];
MD5_u32plus block[16];
};
typedef struct md5_ctx MD5_CTX;
typedef struct md5_ctx my_md5_ctx;
static CURLcode MD5_Init(MD5_CTX *ctx);
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
static CURLcode my_md5_init(my_md5_ctx *ctx);
static void my_md5_update(my_md5_ctx *ctx, const void *data,
unsigned long size);
static void my_md5_final(unsigned char *result, my_md5_ctx *ctx);
/*
* The basic MD5 functions.
@ -323,7 +344,7 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
* This processes one or more 64-byte data blocks, but does NOT update
* the bit counters. There are no alignment requirements.
*/
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
static const void *body(my_md5_ctx *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
@ -431,7 +452,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
return ptr;
}
static CURLcode MD5_Init(MD5_CTX *ctx)
static CURLcode my_md5_init(my_md5_ctx *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
@ -444,7 +465,8 @@ static CURLcode MD5_Init(MD5_CTX *ctx)
return CURLE_OK;
}
static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
static void my_md5_update(my_md5_ctx *ctx, const void *data,
unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used;
@ -479,7 +501,7 @@ static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
memcpy(ctx->buffer, data, size);
}
static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
static void my_md5_final(unsigned char *result, my_md5_ctx *ctx)
{
unsigned long used, available;
@ -535,13 +557,13 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
const struct HMAC_params Curl_HMAC_MD5[] = {
{
/* Hash initialization function. */
CURLX_FUNCTION_CAST(HMAC_hinit_func, MD5_Init),
CURLX_FUNCTION_CAST(HMAC_hinit_func, my_md5_init),
/* Hash update function. */
CURLX_FUNCTION_CAST(HMAC_hupdate_func, MD5_Update),
CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_md5_update),
/* Hash computation end function. */
CURLX_FUNCTION_CAST(HMAC_hfinal_func, MD5_Final),
CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_md5_final),
/* Size of hash context structure. */
sizeof(MD5_CTX),
sizeof(my_md5_ctx),
/* Maximum key length. */
64,
/* Result size. */
@ -552,13 +574,13 @@ const struct HMAC_params Curl_HMAC_MD5[] = {
const struct MD5_params Curl_DIGEST_MD5[] = {
{
/* Digest initialization function */
CURLX_FUNCTION_CAST(Curl_MD5_init_func, MD5_Init),
CURLX_FUNCTION_CAST(Curl_MD5_init_func, my_md5_init),
/* Digest update function */
CURLX_FUNCTION_CAST(Curl_MD5_update_func, MD5_Update),
CURLX_FUNCTION_CAST(Curl_MD5_update_func, my_md5_update),
/* Digest computation end function */
CURLX_FUNCTION_CAST(Curl_MD5_final_func, MD5_Final),
CURLX_FUNCTION_CAST(Curl_MD5_final_func, my_md5_final),
/* Size of digest context struct */
sizeof(MD5_CTX),
sizeof(my_md5_ctx),
/* Result size */
16
}
@ -569,13 +591,13 @@ const struct MD5_params Curl_DIGEST_MD5[] = {
* Returns CURLE_OK on success.
*/
CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
const size_t len)
const size_t len)
{
MD5_CTX ctx;
my_md5_ctx ctx;
MD5_Init(&ctx);
MD5_Update(&ctx, input, curlx_uztoui(len));
MD5_Final(outbuffer, &ctx);
my_md5_init(&ctx);
my_md5_update(&ctx, input, curlx_uztoui(len));
my_md5_final(outbuffer, &ctx);
return CURLE_OK;
}