From 7c6f4beda25d28f92777a2c4720858481f83e5a4 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sat, 5 Feb 2022 14:42:22 -0500 Subject: [PATCH] crypto: do not advertise unsupported algorithms Fixes: https://github.com/nodejs/node/issues/41857 --- src/crypto/crypto_cipher.cc | 9 ++++++++- src/crypto/crypto_hash.cc | 9 ++++++++- src/crypto/crypto_util.h | 30 ++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index de5784b3c8f63d..34f33ac644f02c 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -235,8 +235,15 @@ void CipherBase::GetSSLCiphers(const FunctionCallbackInfo& args) { void CipherBase::GetCiphers(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); + MarkPopErrorOnReturn mark_pop_error_on_return; CipherPushContext ctx(env); - EVP_CIPHER_do_all_sorted(array_push_back, &ctx); + EVP_CIPHER_do_all_sorted( + array_push_back, + &ctx); args.GetReturnValue().Set(ctx.ToJSArray()); } diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 9aa9c604da7dc1..2989bacbd124bb 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -35,8 +35,15 @@ void Hash::MemoryInfo(MemoryTracker* tracker) const { void Hash::GetHashes(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); + MarkPopErrorOnReturn mark_pop_error_on_return; CipherPushContext ctx(env); - EVP_MD_do_all_sorted(array_push_back, &ctx); + EVP_MD_do_all_sorted( + array_push_back, + &ctx); args.GetReturnValue().Set(ctx.ToJSArray()); } diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index 5060fc3f2fbd67..8605eec390e98a 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -616,11 +616,37 @@ class CipherPushContext { Environment* env_; }; -template -void array_push_back(const TypeName* md, +template +void array_push_back(const TypeName* evp_ref, const char* from, const char* to, void* arg) { + if (!from) + return; + + const TypeName* real_instance = getbyname(from); + if (!real_instance) + return; + + const char* real_name = getname(real_instance); + if (!real_name) + return; + + // EVP_*_fetch() does not support alias names, so we need to pass it the + // real/original algorithm name + // We use EVP_*_fetch() as a filter here because it will only return an + // instance if the algorithm is supported by the public OpenSSL APIs (some + // algorithms are used internally by OpenSSL and are also passed to this + // callback) + TypeName* fetched = fetch_type(nullptr, real_name, nullptr); + if (!fetched) + return; + + free_type(fetched); static_cast(arg)->push_back(from); }