From 00b77d9e849342932f196cafe0872a0662ea365d 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 6d5403b563118f..240fc0708e598c 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3233,10 +3233,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; } @@ -3357,7 +3361,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"); } } @@ -3369,6 +3374,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; } @@ -4050,7 +4058,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; @@ -4143,7 +4152,7 @@ void DiffieHellman::New(const FunctionCallbackInfo& args) { } if (!initialized) { - return env->ThrowError("Initialization failed"); + return ThrowCryptoError(env, ERR_get_error(), "Initialization failed"); } } @@ -4154,11 +4163,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); @@ -4177,7 +4186,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); @@ -4195,7 +4204,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); @@ -4213,7 +4222,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) { @@ -4236,7 +4245,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) { @@ -4259,7 +4268,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; @@ -4292,7 +4301,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"); @@ -4329,7 +4338,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) { @@ -4348,7 +4357,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) { @@ -4370,7 +4379,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_); }