Skip to content

Commit f1c8f0c

Browse files
committed
crypto: do not advertise unsupported algorithms
Fixes: #41857
1 parent 92b85e7 commit f1c8f0c

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

src/crypto/crypto_cipher.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,19 @@ void CipherBase::GetSSLCiphers(const FunctionCallbackInfo<Value>& args) {
235235

236236
void CipherBase::GetCiphers(const FunctionCallbackInfo<Value>& args) {
237237
Environment* env = Environment::GetCurrent(args);
238+
MarkPopErrorOnReturn mark_pop_error_on_return;
238239
CipherPushContext ctx(env);
239-
EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &ctx);
240+
EVP_CIPHER_do_all_sorted(
241+
#if OPENSSL_VERSION_MAJOR >= 3
242+
array_push_back<EVP_CIPHER,
243+
EVP_CIPHER_fetch,
244+
EVP_CIPHER_free,
245+
EVP_get_cipherbyname,
246+
EVP_CIPHER_get0_name>,
247+
#else
248+
array_push_back<EVP_CIPHER>,
249+
#endif
250+
&ctx);
240251
args.GetReturnValue().Set(ctx.ToJSArray());
241252
}
242253

src/crypto/crypto_hash.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,19 @@ void Hash::MemoryInfo(MemoryTracker* tracker) const {
3535

3636
void Hash::GetHashes(const FunctionCallbackInfo<Value>& args) {
3737
Environment* env = Environment::GetCurrent(args);
38+
MarkPopErrorOnReturn mark_pop_error_on_return;
3839
CipherPushContext ctx(env);
39-
EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &ctx);
40+
EVP_MD_do_all_sorted(
41+
#if OPENSSL_VERSION_MAJOR >= 3
42+
array_push_back<EVP_MD,
43+
EVP_MD_fetch,
44+
EVP_MD_free,
45+
EVP_get_digestbyname,
46+
EVP_MD_get0_name>,
47+
#else
48+
array_push_back<EVP_MD>,
49+
#endif
50+
&ctx);
4051
args.GetReturnValue().Set(ctx.ToJSArray());
4152
}
4253

src/crypto/crypto_util.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,51 @@ class CipherPushContext {
616616
Environment* env_;
617617
};
618618

619+
#if OPENSSL_VERSION_MAJOR >= 3
620+
template <class TypeName,
621+
TypeName* fetch_type(OSSL_LIB_CTX*, const char*, const char*),
622+
void free_type(TypeName*),
623+
const TypeName* getbyname(const char *),
624+
const char* getname(const TypeName*)>
625+
void array_push_back(const TypeName* evp_ref,
626+
const char* from,
627+
const char* to,
628+
void* arg) {
629+
if (!from)
630+
return;
631+
632+
const TypeName* real_instance = getbyname(from);
633+
if (!real_instance)
634+
return;
635+
636+
const char* real_name = getname(real_instance);
637+
if (!real_name)
638+
return;
639+
640+
// EVP_*_fetch() does not support alias names, so we need to pass it the
641+
// real/original algorithm name
642+
// We use EVP_*_fetch() as a filter here because it will only return an
643+
// instance if the algorithm is supported by the public OpenSSL APIs (some
644+
// algorithms are used internally by OpenSSL and are also passed to this
645+
// callback)
646+
TypeName* fetched = fetch_type(nullptr, real_name, nullptr);
647+
if (!fetched)
648+
return;
649+
650+
free_type(fetched);
651+
static_cast<CipherPushContext*>(arg)->push_back(from);
652+
}
653+
#else
619654
template <class TypeName>
620-
void array_push_back(const TypeName* md,
655+
void array_push_back(const TypeName* evp_ref,
621656
const char* from,
622657
const char* to,
623658
void* arg) {
659+
if (!from)
660+
return;
624661
static_cast<CipherPushContext*>(arg)->push_back(from);
625662
}
663+
#endif
626664

627665
inline bool IsAnyByteSource(v8::Local<v8::Value> arg) {
628666
return arg->IsArrayBufferView() ||

0 commit comments

Comments
 (0)