Browse Source

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 <fedor@indutny.com>
Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
process-exit-stdio-flushing
Stefan Budeanu 9 years ago
committed by Michael Dawson
parent
commit
b7089f67b9
  1. 42
      src/node_crypto.cc

42
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<Value>& 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<Object> 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<Value>& 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<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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<Value>& 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<Value>& 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<Value>& 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<String> property,
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(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_);
}

Loading…
Cancel
Save