From 61140ffe3cccbdbed36667831d0914622db46866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sun, 18 Aug 2019 18:27:53 +0200 Subject: [PATCH] crypto: simplify DSA validation in FIPS mode PR-URL: https://github.com/nodejs/node/pull/29195 Reviewed-By: Anna Henningsen Reviewed-By: Daniel Bevenius Reviewed-By: James M Snell Reviewed-By: Michael Dawson --- src/node_crypto.cc | 72 +++++++++++++++------------------------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index f1c7d1796acc58..de301d77c229c1 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4879,15 +4879,7 @@ static AllocatedBuffer Node_SignFinal(Environment* env, return AllocatedBuffer(); } -Sign::SignResult Sign::SignFinal( - const ManagedEVPPKey& pkey, - int padding, - const Maybe& salt_len) { - if (!mdctx_) - return SignResult(kSignNotInitialised); - - EVPMDPointer mdctx = std::move(mdctx_); - +static inline bool ValidateDSAParameters(EVP_PKEY* key) { #ifdef NODE_FIPS_MODE /* Validate DSA2 parameters from FIPS 186-4 */ if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(pkey.get())) { @@ -4898,23 +4890,29 @@ Sign::SignResult Sign::SignFinal( const BIGNUM* q; DSA_get0_pqg(dsa, nullptr, &q, nullptr); size_t N = BN_num_bits(q); - bool result = false; - - if (L == 1024 && N == 160) - result = true; - else if (L == 2048 && N == 224) - result = true; - else if (L == 2048 && N == 256) - result = true; - else if (L == 3072 && N == 256) - result = true; - - if (!result) { - return SignResult(kSignPrivateKey); - } + + return (L == 1024 && N == 160) || + (L == 2048 && N == 224) || + (L == 2048 && N == 256) || + (L == 3072 && N == 256) } #endif // NODE_FIPS_MODE + return true; +} + +Sign::SignResult Sign::SignFinal( + const ManagedEVPPKey& pkey, + int padding, + const Maybe& salt_len) { + if (!mdctx_) + return SignResult(kSignNotInitialised); + + EVPMDPointer mdctx = std::move(mdctx_); + + if (!ValidateDSAParameters(pkey.get())) + return SignResult(kSignPrivateKey); + AllocatedBuffer buffer = Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len); Error error = buffer.data() == nullptr ? kSignPrivateKey : kSignOk; @@ -4965,32 +4963,8 @@ void SignOneShot(const FunctionCallbackInfo& args) { if (!key) return; -#ifdef NODE_FIPS_MODE - /* Validate DSA2 parameters from FIPS 186-4 */ - if (FIPS_mode() && EVP_PKEY_DSA == EVP_PKEY_base_id(key.get())) { - DSA* dsa = EVP_PKEY_get0_DSA(key.get()); - const BIGNUM* p; - DSA_get0_pqg(dsa, &p, nullptr, nullptr); - size_t L = BN_num_bits(p); - const BIGNUM* q; - DSA_get0_pqg(dsa, nullptr, &q, nullptr); - size_t N = BN_num_bits(q); - bool result = false; - - if (L == 1024 && N == 160) - result = true; - else if (L == 2048 && N == 224) - result = true; - else if (L == 2048 && N == 256) - result = true; - else if (L == 3072 && N == 256) - result = true; - - if (!result) { - return CheckThrow(env, SignBase::Error::kSignPrivateKey); - } - } -#endif // NODE_FIPS_MODE + if (!ValidateDSAParameters(key.get())) + return CheckThrow(env, SignBase::Error::kSignPrivateKey); ArrayBufferViewContents data(args[offset]);