Skip to content

Commit

Permalink
crypto: Make Hmac 1.1.0-compatible
Browse files Browse the repository at this point in the history
OpenSSL 1.1.0 requries HMAC_CTX be heap-allocated.

PR-URL: #16130
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: Rod Vagg <[email protected]>
  • Loading branch information
davidben authored and evanlucas committed Nov 13, 2017
1 parent fa1fc16 commit 5c24fc3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
39 changes: 30 additions & 9 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,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<HMAC_CTX>(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
Expand Down Expand Up @@ -3821,6 +3835,11 @@ void CipherBase::Final(const FunctionCallbackInfo<Value>& args) {
}


Hmac::~Hmac() {
HMAC_CTX_free(ctx_);
}


void Hmac::Initialize(Environment* env, v8::Local<v8::Object> target) {
Local<FunctionTemplate> t = env->NewFunctionTemplate(New);

Expand All @@ -3847,14 +3866,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;
}


Expand All @@ -3871,9 +3892,9 @@ void Hmac::HmacInit(const FunctionCallbackInfo<Value>& args) {


bool Hmac::HmacUpdate(const char* data, int len) {
if (!initialised_)
if (ctx_ == nullptr)
return false;
int r = HMAC_Update(&ctx_, reinterpret_cast<const unsigned char*>(data), len);
int r = HMAC_Update(ctx_, reinterpret_cast<const unsigned char*>(data), len);
return r == 1;
}

Expand Down Expand Up @@ -3918,10 +3939,10 @@ void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& 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<Value> error;
Expand Down
11 changes: 3 additions & 8 deletions src/node_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<v8::Object> target);

Expand All @@ -513,13 +509,12 @@ class Hmac : public BaseObject {

Hmac(Environment* env, v8::Local<v8::Object> wrap)
: BaseObject(env, wrap),
initialised_(false) {
ctx_(nullptr) {
MakeWeak<Hmac>(this);
}

private:
HMAC_CTX ctx_; /* coverity[member_decl] */
bool initialised_;
HMAC_CTX* ctx_;
};

class Hash : public BaseObject {
Expand Down

0 comments on commit 5c24fc3

Please sign in to comment.