From 5e9e4e5bf9610701a334102d6f69fb276868f62e Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 22 Sep 2017 19:05:42 -0400 Subject: [PATCH] crypto: Make Hmac 1.1.0-compatible OpenSSL 1.1.0 requries HMAC_CTX be heap-allocated. PR-URL: https://github.com/nodejs/node/pull/16130 Backport-PR-URL: https://github.com/nodejs/node/pull/18622 Reviewed-By: Ben Noordhuis Reviewed-By: Rod Vagg --- src/node_crypto.cc | 39 ++++++++++++++++++++++++++++++--------- src/node_crypto.h | 11 +++-------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index c0c7cc8c2ca4b4..568964e2d34dcb 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -208,6 +208,20 @@ static int X509_up_ref(X509* cert) { #define EVP_MD_CTX_new EVP_MD_CTX_create #define EVP_MD_CTX_free EVP_MD_CTX_destroy + +HMAC_CTX* HMAC_CTX_new() { + HMAC_CTX* ctx = Malloc(1); + HMAC_CTX_init(ctx); + return ctx; +} + +void HMAC_CTX_free(HMAC_CTX* ctx) { + if (ctx == nullptr) { + return; + } + HMAC_CTX_cleanup(ctx); + free(ctx); +} #endif // OPENSSL_VERSION_NUMBER < 0x10100000L // Subject DER of CNNIC ROOT CA and CNNIC EV ROOT CA are taken from @@ -3825,6 +3839,11 @@ void CipherBase::Final(const FunctionCallbackInfo& args) { } +Hmac::~Hmac() { + HMAC_CTX_free(ctx_); +} + + void Hmac::Initialize(Environment* env, v8::Local target) { Local t = env->NewFunctionTemplate(New); @@ -3852,14 +3871,16 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) { if (md == nullptr) { return env()->ThrowError("Unknown message digest"); } - HMAC_CTX_init(&ctx_); if (key_len == 0) { key = ""; } - if (!HMAC_Init_ex(&ctx_, key, key_len, md, nullptr)) { + ctx_ = HMAC_CTX_new(); + if (ctx_ == nullptr || + !HMAC_Init_ex(ctx_, key, key_len, md, nullptr)) { + HMAC_CTX_free(ctx_); + ctx_ = nullptr; return ThrowCryptoError(env(), ERR_get_error()); } - initialised_ = true; } @@ -3883,9 +3904,9 @@ void Hmac::HmacInit(const FunctionCallbackInfo& args) { bool Hmac::HmacUpdate(const char* data, int len) { - if (!initialised_) + if (ctx_ == nullptr) return false; - int r = HMAC_Update(&ctx_, reinterpret_cast(data), len); + int r = HMAC_Update(ctx_, reinterpret_cast(data), len); return r == 1; } @@ -3936,10 +3957,10 @@ void Hmac::HmacDigest(const FunctionCallbackInfo& args) { unsigned char md_value[EVP_MAX_MD_SIZE]; unsigned int md_len = 0; - if (hmac->initialised_) { - HMAC_Final(&hmac->ctx_, md_value, &md_len); - HMAC_CTX_cleanup(&hmac->ctx_); - hmac->initialised_ = false; + if (hmac->ctx_ != nullptr) { + HMAC_Final(hmac->ctx_, md_value, &md_len); + HMAC_CTX_free(hmac->ctx_); + hmac->ctx_ = nullptr; } Local error; diff --git a/src/node_crypto.h b/src/node_crypto.h index 0f9ef02ea67b75..a014f3f06c4d43 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -494,11 +494,7 @@ class CipherBase : public BaseObject { class Hmac : public BaseObject { public: - ~Hmac() override { - if (!initialised_) - return; - HMAC_CTX_cleanup(&ctx_); - } + ~Hmac() override; static void Initialize(Environment* env, v8::Local target); @@ -513,13 +509,12 @@ class Hmac : public BaseObject { Hmac(Environment* env, v8::Local wrap) : BaseObject(env, wrap), - initialised_(false) { + ctx_(nullptr) { MakeWeak(this); } private: - HMAC_CTX ctx_; /* coverity[member_decl] */ - bool initialised_; + HMAC_CTX* ctx_; }; class Hash : public BaseObject {