From 39dc4086fedfc501eb33b01fc16a34af05f339f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sat, 11 Jul 2020 00:19:40 +0200 Subject: [PATCH] crypto: avoid unitializing ECDH objects on error The previous code changed the private key of the ECDH object, but removed the public key if deriving it from the private key failed. Instead, if deriving the public key fails, neither the private nor the public key stored in the ECDH object should be updated. PR-URL: https://github.com/nodejs/node/pull/34302 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- src/node_crypto.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 8139e73c2ddde5..2236056d016cc6 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5649,21 +5649,20 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { return env->ThrowError("Private key is not valid for specified curve."); } - int result = EC_KEY_set_private_key(ecdh->key_.get(), priv.get()); + ECKeyPointer new_key(EC_KEY_dup(ecdh->key_.get())); + CHECK(new_key); + + int result = EC_KEY_set_private_key(new_key.get(), priv.get()); priv.reset(); if (!result) { return env->ThrowError("Failed to convert BN to a private key"); } - // To avoid inconsistency, clear the current public key in-case computing - // the new one fails for some reason. - EC_KEY_set_public_key(ecdh->key_.get(), nullptr); - MarkPopErrorOnReturn mark_pop_error_on_return; USE(&mark_pop_error_on_return); - const BIGNUM* priv_key = EC_KEY_get0_private_key(ecdh->key_.get()); + const BIGNUM* priv_key = EC_KEY_get0_private_key(new_key.get()); CHECK_NOT_NULL(priv_key); ECPointPointer pub(EC_POINT_new(ecdh->group_)); @@ -5674,8 +5673,11 @@ void ECDH::SetPrivateKey(const FunctionCallbackInfo& args) { return env->ThrowError("Failed to generate ECDH public key"); } - if (!EC_KEY_set_public_key(ecdh->key_.get(), pub.get())) + if (!EC_KEY_set_public_key(new_key.get(), pub.get())) return env->ThrowError("Failed to set generated public key"); + + EC_KEY_copy(ecdh->key_.get(), new_key.get()); + ecdh->group_ = EC_KEY_get0_group(ecdh->key_.get()); }