mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Use EVP_MAC for HMAC (OpenSSL >= 3.0)
The legacy HMAC_CTX interface (HMAC_CTX_new(), HMAC_Init_ex(), etc.) has
been deprecated since OpenSSL 3.0. The legacy routines do not dispatch
through the provider framework, so a loaded provider's HMAC
implementation could be bypassed.
This commit updates hmac_openssl.c to use EVP_MAC when building with
OpenSSL 3.0 or newer versions. OpenSSL 1.1.1 is the oldest version
supported on HEAD, so the legacy routines need to be kept. Note that
LibreSSL uses the legacy routines.
Like b91f79cd08, no backpatch is done.
Author: Mark Atwood <mark@reviewcommit.com>
Co-authored-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://postgr.es/m/178596055149.1584250.13974609482797470185@reviewcommit.com
This commit is contained in:
@@ -22,7 +22,13 @@
|
||||
|
||||
|
||||
#include <openssl/err.h>
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/params.h>
|
||||
#else
|
||||
#include <openssl/hmac.h>
|
||||
#endif
|
||||
|
||||
#include "common/hmac.h"
|
||||
#include "common/md5.h"
|
||||
@@ -58,7 +64,12 @@ typedef enum pg_hmac_errno
|
||||
/* Internal pg_hmac_ctx structure */
|
||||
struct pg_hmac_ctx
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
EVP_MAC *mac;
|
||||
EVP_MAC_CTX *hmacctx;
|
||||
#else
|
||||
HMAC_CTX *hmacctx;
|
||||
#endif
|
||||
pg_cryptohash_type type;
|
||||
pg_hmac_errno error;
|
||||
const char *errreason;
|
||||
@@ -139,10 +150,24 @@ pg_hmac_create(pg_cryptohash_type type)
|
||||
ResourceOwnerEnlarge(CurrentResourceOwner);
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
|
||||
/*
|
||||
* Fetch the HMAC implementation so that it is served by the loaded
|
||||
* provider.
|
||||
*/
|
||||
ctx->mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
|
||||
if (ctx->mac != NULL)
|
||||
ctx->hmacctx = EVP_MAC_CTX_new(ctx->mac);
|
||||
#else
|
||||
ctx->hmacctx = HMAC_CTX_new();
|
||||
#endif
|
||||
|
||||
if (ctx->hmacctx == NULL)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
EVP_MAC_free(ctx->mac);
|
||||
#endif
|
||||
explicit_bzero(ctx, sizeof(pg_hmac_ctx));
|
||||
FREE(ctx);
|
||||
#ifndef FRONTEND
|
||||
@@ -153,7 +178,6 @@ pg_hmac_create(pg_cryptohash_type type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_RESOWNER_FOR_HMAC
|
||||
ctx->resowner = CurrentResourceOwner;
|
||||
ResourceOwnerRememberHMAC(CurrentResourceOwner, ctx);
|
||||
@@ -171,10 +195,43 @@ int
|
||||
pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len)
|
||||
{
|
||||
int status = 0;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
const char *digest = NULL;
|
||||
OSSL_PARAM params[2];
|
||||
#endif
|
||||
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
switch (ctx->type)
|
||||
{
|
||||
case PG_MD5:
|
||||
digest = "MD5";
|
||||
break;
|
||||
case PG_SHA1:
|
||||
digest = "SHA1";
|
||||
break;
|
||||
case PG_SHA224:
|
||||
digest = "SHA224";
|
||||
break;
|
||||
case PG_SHA256:
|
||||
digest = "SHA256";
|
||||
break;
|
||||
case PG_SHA384:
|
||||
digest = "SHA384";
|
||||
break;
|
||||
case PG_SHA512:
|
||||
digest = "SHA512";
|
||||
break;
|
||||
}
|
||||
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
|
||||
unconstify(char *, digest), 0);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
status = EVP_MAC_init(ctx->hmacctx, key, len, params);
|
||||
#else
|
||||
switch (ctx->type)
|
||||
{
|
||||
case PG_MD5:
|
||||
@@ -196,6 +253,7 @@ pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len)
|
||||
status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha512(), NULL);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* OpenSSL internals return 1 on success, 0 on failure */
|
||||
if (status <= 0)
|
||||
@@ -221,7 +279,11 @@ pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len)
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
status = EVP_MAC_update(ctx->hmacctx, data, len);
|
||||
#else
|
||||
status = HMAC_Update(ctx->hmacctx, data, len);
|
||||
#endif
|
||||
|
||||
/* OpenSSL internals return 1 on success, 0 on failure */
|
||||
if (status <= 0)
|
||||
@@ -242,7 +304,11 @@ int
|
||||
pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len)
|
||||
{
|
||||
int status = 0;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
size_t outlen;
|
||||
#else
|
||||
uint32 outlen;
|
||||
#endif
|
||||
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
@@ -293,7 +359,11 @@ pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len)
|
||||
break;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
status = EVP_MAC_final(ctx->hmacctx, dest, &outlen, len);
|
||||
#else
|
||||
status = HMAC_Final(ctx->hmacctx, dest, &outlen);
|
||||
#endif
|
||||
|
||||
/* OpenSSL internals return 1 on success, 0 on failure */
|
||||
if (status <= 0)
|
||||
@@ -316,7 +386,13 @@ pg_hmac_free(pg_hmac_ctx *ctx)
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
EVP_MAC_CTX_free(ctx->hmacctx);
|
||||
EVP_MAC_free(ctx->mac);
|
||||
#else
|
||||
HMAC_CTX_free(ctx->hmacctx);
|
||||
#endif
|
||||
|
||||
#ifdef USE_RESOWNER_FOR_HMAC
|
||||
if (ctx->resowner)
|
||||
ResourceOwnerForgetHMAC(ctx->resowner, ctx);
|
||||
|
||||
Reference in New Issue
Block a user