Skip to content

Commit 42b1af7

Browse files
committed
src: move more openssl api detail behind ncrypto
1 parent e2064b4 commit 42b1af7

12 files changed

+119
-100
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ X509View X509View::From(const SSLCtxPointer& ctx) {
11641164
}
11651165

11661166
std::optional<std::string> X509View::getFingerprint(
1167-
const EVP_MD* method) const {
1167+
const Digest& method) const {
11681168
unsigned int md_size;
11691169
unsigned char md[EVP_MAX_MD_SIZE];
11701170
static constexpr char hex[] = "0123456789ABCDEF";
@@ -1692,8 +1692,11 @@ DataPointer hkdf(const Digest& md,
16921692
}
16931693

16941694
auto ctx = EVPKeyCtxPointer::NewFromID(EVP_PKEY_HKDF);
1695+
// OpenSSL < 3.0.0 accepted only a void* as the argument of
1696+
// EVP_PKEY_CTX_set_hkdf_md.
1697+
const EVP_MD* md_ptr = md;
16951698
if (!ctx || !EVP_PKEY_derive_init(ctx.get()) ||
1696-
!EVP_PKEY_CTX_set_hkdf_md(ctx.get(), md) ||
1699+
!EVP_PKEY_CTX_set_hkdf_md(ctx.get(), md_ptr) ||
16971700
!EVP_PKEY_CTX_add1_hkdf_info(ctx.get(), info.data, info.len)) {
16981701
return {};
16991702
}
@@ -1776,7 +1779,7 @@ DataPointer scrypt(const Buffer<const char>& pass,
17761779
return {};
17771780
}
17781781

1779-
DataPointer pbkdf2(const EVP_MD* md,
1782+
DataPointer pbkdf2(const Digest& md,
17801783
const Buffer<const char>& pass,
17811784
const Buffer<const unsigned char>& salt,
17821785
uint32_t iterations,
@@ -1788,12 +1791,13 @@ DataPointer pbkdf2(const EVP_MD* md,
17881791
}
17891792

17901793
auto dp = DataPointer::Alloc(length);
1794+
const EVP_MD* md_ptr = md;
17911795
if (dp && PKCS5_PBKDF2_HMAC(pass.data,
17921796
pass.len,
17931797
salt.data,
17941798
salt.len,
17951799
iterations,
1796-
md,
1800+
md_ptr,
17971801
length,
17981802
reinterpret_cast<unsigned char*>(dp.get()))) {
17991803
return dp;
@@ -2728,6 +2732,17 @@ bool SSLCtxPointer::setGroups(const char* groups) {
27282732
return SSL_CTX_set1_groups_list(get(), groups) == 1;
27292733
}
27302734

2735+
bool SSLCtxPointer::setCipherSuites(std::string_view ciphers) {
2736+
#ifndef OPENSSL_IS_BORINGSSL
2737+
if (!ctx_) return false;
2738+
return SSL_CTX_set_ciphersuites(ctx_.get(), ciphers.data());
2739+
#else
2740+
// BoringSSL does not allow API config of TLS 1.3 cipher suites.
2741+
// We treat this as a non-op.
2742+
return true;
2743+
#endif
2744+
}
2745+
27312746
// ============================================================================
27322747

27332748
const Cipher Cipher::FromName(std::string_view name) {
@@ -3335,14 +3350,16 @@ bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) {
33353350
EVP_PKEY_CTX_set_ec_param_enc(ctx_.get(), encoding) == 1;
33363351
}
33373352

3338-
bool EVPKeyCtxPointer::setRsaOaepMd(const EVP_MD* md) {
3339-
if (md == nullptr || !ctx_) return false;
3340-
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx_.get(), md) > 0;
3353+
bool EVPKeyCtxPointer::setRsaOaepMd(const Digest& md) {
3354+
if (!md || !ctx_) return false;
3355+
const EVP_MD* md_ptr = md;
3356+
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx_.get(), md_ptr) > 0;
33413357
}
33423358

3343-
bool EVPKeyCtxPointer::setRsaMgf1Md(const EVP_MD* md) {
3344-
if (md == nullptr || !ctx_) return false;
3345-
return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx_.get(), md) > 0;
3359+
bool EVPKeyCtxPointer::setRsaMgf1Md(const Digest& md) {
3360+
if (!md || !ctx_) return false;
3361+
const EVP_MD* md_ptr = md;
3362+
return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx_.get(), md_ptr) > 0;
33463363
}
33473364

33483365
bool EVPKeyCtxPointer::setRsaPadding(int padding) {
@@ -3377,14 +3394,17 @@ bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) {
33773394
return false;
33783395
}
33793396

3380-
bool EVPKeyCtxPointer::setRsaPssKeygenMd(const EVP_MD* md) {
3381-
if (md == nullptr || !ctx_) return false;
3382-
return EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx_.get(), md) > 0;
3397+
bool EVPKeyCtxPointer::setRsaPssKeygenMd(const Digest& md) {
3398+
if (!md || !ctx_) return false;
3399+
// OpenSSL < 3 accepts a void* for the md parameter.
3400+
const EVP_MD* md_ptr = md;
3401+
return EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx_.get(), md_ptr) > 0;
33833402
}
33843403

3385-
bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md(const EVP_MD* md) {
3386-
if (md == nullptr || !ctx_) return false;
3387-
return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx_.get(), md) > 0;
3404+
bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md(const Digest& md) {
3405+
if (!md || !ctx_) return false;
3406+
const EVP_MD* md_ptr = md;
3407+
return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx_.get(), md_ptr) > 0;
33883408
}
33893409

33903410
bool EVPKeyCtxPointer::setRsaPssSaltlen(int salt_len) {
@@ -3858,7 +3878,7 @@ EVP_MD_CTX* EVPMDCtxPointer::release() {
38583878
return ctx_.release();
38593879
}
38603880

3861-
bool EVPMDCtxPointer::digestInit(const EVP_MD* digest) {
3881+
bool EVPMDCtxPointer::digestInit(const Digest& digest) {
38623882
if (!ctx_) return false;
38633883
return EVP_DigestInit_ex(ctx_.get(), digest, nullptr) > 0;
38643884
}
@@ -3924,7 +3944,7 @@ bool EVPMDCtxPointer::copyTo(const EVPMDCtxPointer& other) const {
39243944
}
39253945

39263946
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
3927-
const EVP_MD* digest) {
3947+
const Digest& digest) {
39283948
EVP_PKEY_CTX* ctx = nullptr;
39293949
if (!EVP_DigestSignInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
39303950
return std::nullopt;
@@ -3933,7 +3953,7 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
39333953
}
39343954

39353955
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInit(
3936-
const EVPKeyPointer& key, const EVP_MD* digest) {
3956+
const EVPKeyPointer& key, const Digest& digest) {
39373957
EVP_PKEY_CTX* ctx = nullptr;
39383958
if (!EVP_DigestVerifyInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
39393959
return std::nullopt;
@@ -4030,9 +4050,10 @@ HMAC_CTX* HMACCtxPointer::release() {
40304050
return ctx_.release();
40314051
}
40324052

4033-
bool HMACCtxPointer::init(const Buffer<const void>& buf, const EVP_MD* md) {
4053+
bool HMACCtxPointer::init(const Buffer<const void>& buf, const Digest& md) {
40344054
if (!ctx_) return false;
4035-
return HMAC_Init_ex(ctx_.get(), buf.data, buf.len, md, nullptr) == 1;
4055+
const EVP_MD* md_ptr = md;
4056+
return HMAC_Init_ex(ctx_.get(), buf.data, buf.len, md_ptr, nullptr) == 1;
40364057
}
40374058

40384059
bool HMACCtxPointer::update(const Buffer<const void>& buf) {

deps/ncrypto/ncrypto.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ struct Buffer {
249249

250250
class Digest final {
251251
public:
252+
static constexpr size_t MAX_SIZE = EVP_MAX_MD_SIZE;
252253
Digest() = default;
253254
Digest(const EVP_MD* md) : md_(md) {}
254255
Digest(const Digest&) = default;
@@ -353,7 +354,7 @@ class Cipher final {
353354

354355
struct CipherParams {
355356
int padding;
356-
const EVP_MD* digest;
357+
Digest digest;
357358
const Buffer<const void> label;
358359
};
359360

@@ -723,13 +724,13 @@ class EVPKeyCtxPointer final {
723724
bool setDsaParameters(uint32_t bits, std::optional<int> q_bits);
724725
bool setEcParameters(int curve, int encoding);
725726

726-
bool setRsaOaepMd(const EVP_MD* md);
727-
bool setRsaMgf1Md(const EVP_MD* md);
727+
bool setRsaOaepMd(const Digest& md);
728+
bool setRsaMgf1Md(const Digest& md);
728729
bool setRsaPadding(int padding);
729730
bool setRsaKeygenPubExp(BignumPointer&& e);
730731
bool setRsaKeygenBits(int bits);
731-
bool setRsaPssKeygenMd(const EVP_MD* md);
732-
bool setRsaPssKeygenMgf1Md(const EVP_MD* md);
732+
bool setRsaPssKeygenMd(const Digest& md);
733+
bool setRsaPssKeygenMgf1Md(const Digest& md);
733734
bool setRsaPssSaltlen(int salt_len);
734735
bool setRsaImplicitRejection();
735736
bool setRsaOaepLabel(DataPointer&& data);
@@ -1003,6 +1004,8 @@ class SSLCtxPointer final {
10031004
SSL_CTX_set_tlsext_status_arg(get(), nullptr);
10041005
}
10051006

1007+
bool setCipherSuites(std::string_view ciphers);
1008+
10061009
static SSLCtxPointer NewServer();
10071010
static SSLCtxPointer NewClient();
10081011
static SSLCtxPointer New(const SSL_METHOD* method = TLS_method());
@@ -1131,7 +1134,7 @@ class X509View final {
11311134
bool checkPrivateKey(const EVPKeyPointer& pkey) const;
11321135
bool checkPublicKey(const EVPKeyPointer& pkey) const;
11331136

1134-
std::optional<std::string> getFingerprint(const EVP_MD* method) const;
1137+
std::optional<std::string> getFingerprint(const Digest& method) const;
11351138

11361139
X509Pointer clone() const;
11371140

@@ -1327,16 +1330,16 @@ class EVPMDCtxPointer final {
13271330
void reset(EVP_MD_CTX* ctx = nullptr);
13281331
EVP_MD_CTX* release();
13291332

1330-
bool digestInit(const EVP_MD* digest);
1333+
bool digestInit(const Digest& digest);
13311334
bool digestUpdate(const Buffer<const void>& in);
13321335
DataPointer digestFinal(size_t length);
13331336
bool digestFinalInto(Buffer<void>* buf);
13341337
size_t getExpectedSize();
13351338

13361339
std::optional<EVP_PKEY_CTX*> signInit(const EVPKeyPointer& key,
1337-
const EVP_MD* digest);
1340+
const Digest& digest);
13381341
std::optional<EVP_PKEY_CTX*> verifyInit(const EVPKeyPointer& key,
1339-
const EVP_MD* digest);
1342+
const Digest& digest);
13401343

13411344
DataPointer signOneShot(const Buffer<const unsigned char>& buf) const;
13421345
DataPointer sign(const Buffer<const unsigned char>& buf) const;
@@ -1371,7 +1374,7 @@ class HMACCtxPointer final {
13711374
void reset(HMAC_CTX* ctx = nullptr);
13721375
HMAC_CTX* release();
13731376

1374-
bool init(const Buffer<const void>& buf, const EVP_MD* md);
1377+
bool init(const Buffer<const void>& buf, const Digest& md);
13751378
bool update(const Buffer<const void>& buf);
13761379
DataPointer digest();
13771380
bool digestInto(Buffer<void>* buf);
@@ -1486,7 +1489,7 @@ DataPointer scrypt(const Buffer<const char>& pass,
14861489
uint64_t maxmem,
14871490
size_t length);
14881491

1489-
DataPointer pbkdf2(const EVP_MD* md,
1492+
DataPointer pbkdf2(const Digest& md,
14901493
const Buffer<const char>& pass,
14911494
const Buffer<const unsigned char>& salt,
14921495
uint32_t iterations,

src/crypto/crypto_context.cc

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ namespace node {
3131

3232
using ncrypto::BignumPointer;
3333
using ncrypto::BIOPointer;
34+
using ncrypto::Cipher;
3435
using ncrypto::ClearErrorOnReturn;
3536
using ncrypto::CryptoErrorList;
3637
using ncrypto::DHPointer;
38+
using ncrypto::Digest;
3739
#ifndef OPENSSL_NO_ENGINE
3840
using ncrypto::EnginePointer;
3941
#endif // !OPENSSL_NO_ENGINE
@@ -1518,8 +1520,6 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
15181520
}
15191521

15201522
void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
1521-
// BoringSSL doesn't allow API config of TLS1.3 cipher suites.
1522-
#ifndef OPENSSL_IS_BORINGSSL
15231523
SecureContext* sc;
15241524
ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
15251525
Environment* env = sc->env();
@@ -1529,9 +1529,9 @@ void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
15291529
CHECK(args[0]->IsString());
15301530

15311531
const Utf8Value ciphers(env->isolate(), args[0]);
1532-
if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
1532+
if (!sc->ctx_.setCipherSuites(ciphers.ToStringView())) {
15331533
return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
1534-
#endif
1534+
}
15351535
}
15361536

15371537
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
@@ -2010,25 +2010,14 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
20102010
}
20112011

20122012
ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
2013-
HMAC_Init_ex(hctx,
2014-
hmac_buf.data(),
2015-
hmac_buf.length(),
2016-
EVP_sha256(),
2017-
nullptr);
2013+
HMAC_Init_ex(
2014+
hctx, hmac_buf.data(), hmac_buf.length(), Digest::SHA256, nullptr);
20182015

20192016
ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
20202017
if (enc) {
2021-
EVP_EncryptInit_ex(ectx,
2022-
EVP_aes_128_cbc(),
2023-
nullptr,
2024-
aes_key.data(),
2025-
iv);
2018+
EVP_EncryptInit_ex(ectx, Cipher::AES_128_CBC, nullptr, aes_key.data(), iv);
20262019
} else {
2027-
EVP_DecryptInit_ex(ectx,
2028-
EVP_aes_128_cbc(),
2029-
nullptr,
2030-
aes_key.data(),
2031-
iv);
2020+
EVP_DecryptInit_ex(ectx, Cipher::AES_128_CBC, nullptr, aes_key.data(), iv);
20322021
}
20332022

20342023
return r;
@@ -2047,11 +2036,11 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
20472036
memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
20482037
if (!ncrypto::CSPRNG(iv, 16) ||
20492038
EVP_EncryptInit_ex(
2050-
ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, iv) <= 0 ||
2039+
ectx, Cipher::AES_128_CBC, nullptr, sc->ticket_key_aes_, iv) <= 0 ||
20512040
HMAC_Init_ex(hctx,
20522041
sc->ticket_key_hmac_,
20532042
sizeof(sc->ticket_key_hmac_),
2054-
EVP_sha256(),
2043+
Digest::SHA256,
20552044
nullptr) <= 0) {
20562045
return -1;
20572046
}
@@ -2063,10 +2052,13 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
20632052
return 0;
20642053
}
20652054

2066-
if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
2067-
iv) <= 0 ||
2068-
HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
2069-
EVP_sha256(), nullptr) <= 0) {
2055+
if (EVP_DecryptInit_ex(
2056+
ectx, Cipher::AES_128_CBC, nullptr, sc->ticket_key_aes_, iv) <= 0 ||
2057+
HMAC_Init_ex(hctx,
2058+
sc->ticket_key_hmac_,
2059+
sizeof(sc->ticket_key_hmac_),
2060+
Digest::SHA256,
2061+
nullptr) <= 0) {
20702062
return -1;
20712063
}
20722064
return 1;

src/crypto/crypto_hmac.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace node {
1515

16+
using ncrypto::Digest;
1617
using ncrypto::HMACCtxPointer;
1718
using v8::Boolean;
1819
using v8::FunctionCallbackInfo;
@@ -70,8 +71,8 @@ void Hmac::New(const FunctionCallbackInfo<Value>& args) {
7071
void Hmac::HmacInit(const char* hash_type, const char* key, int key_len) {
7172
HandleScope scope(env()->isolate());
7273

73-
const EVP_MD* md = ncrypto::getDigestByName(hash_type);
74-
if (md == nullptr) [[unlikely]] {
74+
Digest md = Digest::FromName(hash_type);
75+
if (!md) [[unlikely]] {
7576
return THROW_ERR_CRYPTO_INVALID_DIGEST(
7677
env(), "Invalid digest: %s", hash_type);
7778
}
@@ -130,7 +131,7 @@ void Hmac::HmacDigest(const FunctionCallbackInfo<Value>& args) {
130131
encoding = ParseEncoding(env->isolate(), args[0], BUFFER);
131132
}
132133

133-
unsigned char md_value[EVP_MAX_MD_SIZE];
134+
unsigned char md_value[Digest::MAX_SIZE];
134135
ncrypto::Buffer<void> buf{
135136
.data = md_value,
136137
.len = sizeof(md_value),
@@ -199,8 +200,8 @@ Maybe<void> HmacTraits::AdditionalConfig(
199200
CHECK(args[offset + 2]->IsObject()); // Key
200201

201202
Utf8Value digest(env->isolate(), args[offset + 1]);
202-
params->digest = ncrypto::getDigestByName(digest.ToStringView());
203-
if (params->digest == nullptr) [[unlikely]] {
203+
params->digest = Digest::FromName(digest.ToStringView());
204+
if (!params->digest) [[unlikely]] {
204205
THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *digest);
205206
return Nothing<void>();
206207
}

src/crypto/crypto_hmac.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct HmacConfig final : public MemoryRetainer {
4545
KeyObjectData key;
4646
ByteSource data;
4747
ByteSource signature;
48-
const EVP_MD* digest;
48+
ncrypto::Digest digest;
4949

5050
HmacConfig() = default;
5151

0 commit comments

Comments
 (0)