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>
v4.x
Stefan Budeanu 9 years ago
committed by James M Snell
parent
commit
f7643eed00
  1. 42
      src/node_crypto.cc

42
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"); return env()->ThrowError("Unknown message digest");
} }
HMAC_CTX_init(&ctx_); HMAC_CTX_init(&ctx_);
int result = 0;
if (key_len == 0) { if (key_len == 0) {
HMAC_Init(&ctx_, "", 0, md_); result = HMAC_Init(&ctx_, "", 0, md_);
} else { } 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; initialised_ = true;
} }
@ -3357,7 +3361,8 @@ void Hash::New(const FunctionCallbackInfo<Value>& args) {
Hash* hash = new Hash(env, args.This()); Hash* hash = new Hash(env, args.This());
if (!hash->HashInit(*hash_type)) { 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; return false;
EVP_MD_CTX_init(&mdctx_); EVP_MD_CTX_init(&mdctx_);
EVP_DigestInit_ex(&mdctx_, md_, nullptr); EVP_DigestInit_ex(&mdctx_, md_, nullptr);
if (0 != ERR_peek_error()) {
return false;
}
initialised_ = true; initialised_ = true;
return true; return true;
} }
@ -4050,7 +4058,8 @@ void DiffieHellman::Initialize(Environment* env, Local<Object> target) {
bool DiffieHellman::Init(int primeLength, int g) { bool DiffieHellman::Init(int primeLength, int g) {
dh = DH_new(); 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(); bool result = VerifyContext();
if (!result) if (!result)
return false; return false;
@ -4143,7 +4152,7 @@ void DiffieHellman::New(const FunctionCallbackInfo<Value>& args) {
} }
if (!initialized) { if (!initialized) {
return env->ThrowError("Initialization failed"); return ThrowCryptoError(env, ERR_get_error(), "Initialization failed");
} }
} }
@ -4154,11 +4163,11 @@ void DiffieHellman::GenerateKeys(const FunctionCallbackInfo<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
if (!DH_generate_key(diffieHellman->dh)) { 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); int dataSize = BN_num_bytes(diffieHellman->dh->pub_key);
@ -4177,7 +4186,7 @@ void DiffieHellman::GetPrime(const FunctionCallbackInfo<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
int dataSize = BN_num_bytes(diffieHellman->dh->p); int dataSize = BN_num_bytes(diffieHellman->dh->p);
@ -4195,7 +4204,7 @@ void DiffieHellman::GetGenerator(const FunctionCallbackInfo<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
int dataSize = BN_num_bytes(diffieHellman->dh->g); int dataSize = BN_num_bytes(diffieHellman->dh->g);
@ -4213,7 +4222,7 @@ void DiffieHellman::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
if (diffieHellman->dh->pub_key == nullptr) { if (diffieHellman->dh->pub_key == nullptr) {
@ -4236,7 +4245,7 @@ void DiffieHellman::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
if (diffieHellman->dh->priv_key == nullptr) { if (diffieHellman->dh->priv_key == nullptr) {
@ -4259,7 +4268,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
ClearErrorOnReturn clear_error_on_return; ClearErrorOnReturn clear_error_on_return;
@ -4292,7 +4301,7 @@ void DiffieHellman::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
delete[] data; delete[] data;
if (!checked) { if (!checked) {
return env->ThrowError("Invalid key"); return ThrowCryptoError(env, ERR_get_error(), "Invalid Key");
} else if (checkResult) { } else if (checkResult) {
if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) { if (checkResult & DH_CHECK_PUBKEY_TOO_SMALL) {
return env->ThrowError("Supplied key is too small"); return env->ThrowError("Supplied key is too small");
@ -4329,7 +4338,7 @@ void DiffieHellman::SetPublicKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = diffieHellman->env(); Environment* env = diffieHellman->env();
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
if (args.Length() == 0) { if (args.Length() == 0) {
@ -4348,7 +4357,7 @@ void DiffieHellman::SetPrivateKey(const FunctionCallbackInfo<Value>& args) {
Environment* env = diffieHellman->env(); Environment* env = diffieHellman->env();
if (!diffieHellman->initialised_) { if (!diffieHellman->initialised_) {
return env->ThrowError("Not initialized"); return ThrowCryptoError(env, ERR_get_error(), "Not initialized");
} }
if (args.Length() == 0) { if (args.Length() == 0) {
@ -4370,7 +4379,8 @@ void DiffieHellman::VerifyErrorGetter(Local<String> property,
DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder()); DiffieHellman* diffieHellman = Unwrap<DiffieHellman>(args.Holder());
if (!diffieHellman->initialised_) if (!diffieHellman->initialised_)
return diffieHellman->env()->ThrowError("Not initialized"); return ThrowCryptoError(diffieHellman->env(), ERR_get_error(),
"Not initialized");
args.GetReturnValue().Set(diffieHellman->verifyError_); args.GetReturnValue().Set(diffieHellman->verifyError_);
} }

Loading…
Cancel
Save