From b7089f67b9ab74993aa0703f70a49a262885f944 Mon Sep 17 00:00:00 2001 From: Stefan Budeanu Date: Sun, 8 Nov 2015 19:18:55 -0500 Subject: [PATCH] crypto: Improve error checking and reporting Added checks where necessary to prevent hard crashes and gave precedence to returning the OpenSSL error strings instead of generic error strings. PR-URL: https://github.com/nodejs/node/pull/3753 Reviewed-By: Fedor Indutny Reviewed-By: Shigeki Ohtsu Reviewed-By: Michael Dawson --- src/node_crypto.cc | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 2bbfa0552b..f20c9e2c1d 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3394,10 +3394,14 @@ void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) { return env()->ThrowError("Unknown message digest"); } HMAC_CTX_init(&ctx_); + int result = 0; if (key_len == 0) { - HMAC_Init(&ctx_, "", 0, md_); + result = HMAC_Init(&ctx_, "", 0, md_); } else { - HMAC_Init(&ctx_, key, key_len, md_); + result = HMAC_Init(&ctx_, key, key_len, md_); + } + if (!result) { + return ThrowCryptoError(env(), ERR_get_error()); } initialised_ = true; } @@ -3518,7 +3522,8 @@ void Hash::New(const FunctionCallbackInfo& args) { Hash* hash = new Hash(env, args.This()); if (!hash->HashInit(*hash_type)) { - return env->ThrowError("Digest method not supported"); + return ThrowCryptoError(env, ERR_get_error(), + "Digest method not supported"); } } @@ -3530,6 +3535,9 @@ bool Hash::HashInit(const char* hash_type) { return false; EVP_MD_CTX_init(&mdctx_); EVP_DigestInit_ex(&mdctx_, md_, nullptr); + if (0 != ERR_peek_error()) { + return false; + } initialised_ = true; return true; } @@ -4211,7 +4219,8 @@ void DiffieHellman::Initialize(Environment* env, Local target) { bool DiffieHellman::Init(int primeLength, int g) { dh = DH_new(); - DH_generate_parameters_ex(dh, primeLength, g, 0); + if (!DH_generate_parameters_ex(dh, primeLength, g, 0)) + return false; bool result = VerifyContext(); if (!result) return false; @@ -4304,7 +4313,7 @@ void DiffieHellman::New(const FunctionCallbackInfo& args) { } if (!initialized) { - return env->ThrowError("Initialization failed"); + return ThrowCryptoError(env, ERR_get_error(), "Initialization failed"); } } @@ -4315,11 +4324,11 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } if (!DH_generate_key(diffieHellman->dh)) { - return env->ThrowError("Key generation failed"); + return ThrowCryptoError(env, ERR_get_error(), "Key generation failed"); } int dataSize = BN_num_bytes(diffieHellman->dh->pub_key); @@ -4338,7 +4347,7 @@ void DiffieHellman::GetPrime(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } int dataSize = BN_num_bytes(diffieHellman->dh->p); @@ -4356,7 +4365,7 @@ void DiffieHellman::GetGenerator(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } int dataSize = BN_num_bytes(diffieHellman->dh->g); @@ -4374,7 +4383,7 @@ void DiffieHellman::GetPublicKey(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } if (diffieHellman->dh->pub_key == nullptr) { @@ -4397,7 +4406,7 @@ void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } if (diffieHellman->dh->priv_key == nullptr) { @@ -4420,7 +4429,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo& args) { DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } ClearErrorOnReturn clear_error_on_return; @@ -4453,7 +4462,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo& args) { delete[] data; if (!checked) { - return env->ThrowError("Invalid key"); + return ThrowCryptoError(env, ERR_get_error(), "Invalid Key"); } else if (checkResult) { if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) { return env->ThrowError("Supplied key is too small"); @@ -4490,7 +4499,7 @@ void DiffieHellman::SetPublicKey(const FunctionCallbackInfo& args) { Environment* env = diffieHellman->env(); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } if (args.Length() == 0) { @@ -4509,7 +4518,7 @@ void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo& args) { Environment* env = diffieHellman->env(); if (!diffieHellman->initialised_) { - return env->ThrowError("Not initialized"); + return ThrowCryptoError(env, ERR_get_error(), "Not initialized"); } if (args.Length() == 0) { @@ -4531,7 +4540,8 @@ void DiffieHellman::VerifyErrorGetter(Local property, DiffieHellman* diffieHellman = Unwrap(args.Holder()); if (!diffieHellman->initialised_) - return diffieHellman->env()->ThrowError("Not initialized"); + return ThrowCryptoError(diffieHellman->env(), ERR_get_error(), + "Not initialized"); args.GetReturnValue().Set(diffieHellman->verifyError_); }