diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index de5784b3c8f63d..90a0c4d1fd0bf4 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -235,8 +235,19 @@ 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( +#if OPENSSL_VERSION_MAJOR >= 3 + array_push_back, +#else + array_push_back, +#endif + &ctx); args.GetReturnValue().Set(ctx.ToJSArray()); } diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc index 9aa9c604da7dc1..ceea9e595708ba 100644 --- a/src/crypto/crypto_hash.cc +++ b/src/crypto/crypto_hash.cc @@ -35,8 +35,19 @@ 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( +#if OPENSSL_VERSION_MAJOR >= 3 + array_push_back, +#else + array_push_back, +#endif + &ctx); args.GetReturnValue().Set(ctx.ToJSArray()); } diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h index 5060fc3f2fbd67..9f2fc763751af4 100644 --- a/src/crypto/crypto_util.h +++ b/src/crypto/crypto_util.h @@ -616,13 +616,51 @@ class CipherPushContext { Environment* env_; }; +#if OPENSSL_VERSION_MAJOR >= 3 +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); +} +#else template -void array_push_back(const TypeName* md, +void array_push_back(const TypeName* evp_ref, const char* from, const char* to, void* arg) { + if (!from) + return; static_cast(arg)->push_back(from); } +#endif inline bool IsAnyByteSource(v8::Local arg) { return arg->IsArrayBufferView() ||