Skip to content

Commit

Permalink
crypto: Improve error checking and reporting
Browse files Browse the repository at this point in the history
Added checks where necessary to prevent hard crashes and gave
precedence to returning the OpenSSL error strings instead of generic
error strings.

PR-URL: #3753
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Shigeki Ohtsu <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
  • Loading branch information
stefanmb authored and rvagg committed Nov 13, 2015
1 parent 530bb91 commit 2c9fb14
Showing 1 changed file with 26 additions and 16 deletions.
42 changes: 26 additions & 16 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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");
}
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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");
}
}

Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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_);
}
Expand Down

0 comments on commit 2c9fb14

Please sign in to comment.