Skip to content

Commit ec43618

Browse files
committed
src: move more openssl api detail behind ncrypto
1 parent a34cb1b commit ec43618

File tree

12 files changed

+109
-95
lines changed

12 files changed

+109
-95
lines changed

deps/ncrypto/ncrypto.cc

Lines changed: 32 additions & 16 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,
@@ -2728,6 +2731,17 @@ bool SSLCtxPointer::setGroups(const char* groups) {
27282731
return SSL_CTX_set1_groups_list(get(), groups) == 1;
27292732
}
27302733

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

27332747
const Cipher Cipher::FromName(std::string_view name) {
@@ -3335,13 +3349,13 @@ bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) {
33353349
EVP_PKEY_CTX_set_ec_param_enc(ctx_.get(), encoding) == 1;
33363350
}
33373351

3338-
bool EVPKeyCtxPointer::setRsaOaepMd(const EVP_MD* md) {
3339-
if (md == nullptr || !ctx_) return false;
3352+
bool EVPKeyCtxPointer::setRsaOaepMd(const Digest& md) {
3353+
if (!md || !ctx_) return false;
33403354
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx_.get(), md) > 0;
33413355
}
33423356

3343-
bool EVPKeyCtxPointer::setRsaMgf1Md(const EVP_MD* md) {
3344-
if (md == nullptr || !ctx_) return false;
3357+
bool EVPKeyCtxPointer::setRsaMgf1Md(const Digest& md) {
3358+
if (!md || !ctx_) return false;
33453359
return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx_.get(), md) > 0;
33463360
}
33473361

@@ -3377,13 +3391,15 @@ bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) {
33773391
return false;
33783392
}
33793393

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;
3394+
bool EVPKeyCtxPointer::setRsaPssKeygenMd(const Digest& md) {
3395+
if (!md || !ctx_) return false;
3396+
// OpenSSL < 3 accepts a void* for the md parameter.
3397+
const EVP_MD* md_ptr = md;
3398+
return EVP_PKEY_CTX_set_rsa_pss_keygen_md(ctx_.get(), md_ptr) > 0;
33833399
}
33843400

3385-
bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md(const EVP_MD* md) {
3386-
if (md == nullptr || !ctx_) return false;
3401+
bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md(const Digest& md) {
3402+
if (!md || !ctx_) return false;
33873403
return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(ctx_.get(), md) > 0;
33883404
}
33893405

@@ -3858,7 +3874,7 @@ EVP_MD_CTX* EVPMDCtxPointer::release() {
38583874
return ctx_.release();
38593875
}
38603876

3861-
bool EVPMDCtxPointer::digestInit(const EVP_MD* digest) {
3877+
bool EVPMDCtxPointer::digestInit(const Digest& digest) {
38623878
if (!ctx_) return false;
38633879
return EVP_DigestInit_ex(ctx_.get(), digest, nullptr) > 0;
38643880
}
@@ -3924,7 +3940,7 @@ bool EVPMDCtxPointer::copyTo(const EVPMDCtxPointer& other) const {
39243940
}
39253941

39263942
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
3927-
const EVP_MD* digest) {
3943+
const Digest& digest) {
39283944
EVP_PKEY_CTX* ctx = nullptr;
39293945
if (!EVP_DigestSignInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
39303946
return std::nullopt;
@@ -3933,7 +3949,7 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
39333949
}
39343950

39353951
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInit(
3936-
const EVPKeyPointer& key, const EVP_MD* digest) {
3952+
const EVPKeyPointer& key, const Digest& digest) {
39373953
EVP_PKEY_CTX* ctx = nullptr;
39383954
if (!EVP_DigestVerifyInit(ctx_.get(), &ctx, digest, nullptr, key.get())) {
39393955
return std::nullopt;
@@ -4030,7 +4046,7 @@ HMAC_CTX* HMACCtxPointer::release() {
40304046
return ctx_.release();
40314047
}
40324048

4033-
bool HMACCtxPointer::init(const Buffer<const void>& buf, const EVP_MD* md) {
4049+
bool HMACCtxPointer::init(const Buffer<const void>& buf, const Digest& md) {
40344050
if (!ctx_) return false;
40354051
return HMAC_Init_ex(ctx_.get(), buf.data, buf.len, md, nullptr) == 1;
40364052
}

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
@@ -1440,8 +1442,6 @@ void SecureContext::AddRootCerts(const FunctionCallbackInfo<Value>& args) {
14401442
}
14411443

14421444
void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
1443-
// BoringSSL doesn't allow API config of TLS1.3 cipher suites.
1444-
#ifndef OPENSSL_IS_BORINGSSL
14451445
SecureContext* sc;
14461446
ASSIGN_OR_RETURN_UNWRAP(&sc, args.This());
14471447
Environment* env = sc->env();
@@ -1451,9 +1451,9 @@ void SecureContext::SetCipherSuites(const FunctionCallbackInfo<Value>& args) {
14511451
CHECK(args[0]->IsString());
14521452

14531453
const Utf8Value ciphers(env->isolate(), args[0]);
1454-
if (!SSL_CTX_set_ciphersuites(sc->ctx_.get(), *ciphers))
1454+
if (!sc->ctx_.setCipherSuites(ciphers.ToStringView())) {
14551455
return ThrowCryptoError(env, ERR_get_error(), "Failed to set ciphers");
1456-
#endif
1456+
}
14571457
}
14581458

14591459
void SecureContext::SetCiphers(const FunctionCallbackInfo<Value>& args) {
@@ -1932,25 +1932,14 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
19321932
}
19331933

19341934
ArrayBufferViewContents<unsigned char> hmac_buf(hmac);
1935-
HMAC_Init_ex(hctx,
1936-
hmac_buf.data(),
1937-
hmac_buf.length(),
1938-
EVP_sha256(),
1939-
nullptr);
1935+
HMAC_Init_ex(
1936+
hctx, hmac_buf.data(), hmac_buf.length(), Digest::SHA256, nullptr);
19401937

19411938
ArrayBufferViewContents<unsigned char> aes_key(aes.As<ArrayBufferView>());
19421939
if (enc) {
1943-
EVP_EncryptInit_ex(ectx,
1944-
EVP_aes_128_cbc(),
1945-
nullptr,
1946-
aes_key.data(),
1947-
iv);
1940+
EVP_EncryptInit_ex(ectx, Cipher::AES_128_CBC, nullptr, aes_key.data(), iv);
19481941
} else {
1949-
EVP_DecryptInit_ex(ectx,
1950-
EVP_aes_128_cbc(),
1951-
nullptr,
1952-
aes_key.data(),
1953-
iv);
1942+
EVP_DecryptInit_ex(ectx, Cipher::AES_128_CBC, nullptr, aes_key.data(), iv);
19541943
}
19551944

19561945
return r;
@@ -1969,11 +1958,11 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
19691958
memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
19701959
if (!ncrypto::CSPRNG(iv, 16) ||
19711960
EVP_EncryptInit_ex(
1972-
ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, iv) <= 0 ||
1961+
ectx, Cipher::AES_128_CBC, nullptr, sc->ticket_key_aes_, iv) <= 0 ||
19731962
HMAC_Init_ex(hctx,
19741963
sc->ticket_key_hmac_,
19751964
sizeof(sc->ticket_key_hmac_),
1976-
EVP_sha256(),
1965+
Digest::SHA256,
19771966
nullptr) <= 0) {
19781967
return -1;
19791968
}
@@ -1985,10 +1974,13 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
19851974
return 0;
19861975
}
19871976

1988-
if (EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_,
1989-
iv) <= 0 ||
1990-
HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
1991-
EVP_sha256(), nullptr) <= 0) {
1977+
if (EVP_DecryptInit_ex(
1978+
ectx, Cipher::AES_128_CBC, nullptr, sc->ticket_key_aes_, iv) <= 0 ||
1979+
HMAC_Init_ex(hctx,
1980+
sc->ticket_key_hmac_,
1981+
sizeof(sc->ticket_key_hmac_),
1982+
Digest::SHA256,
1983+
nullptr) <= 0) {
19921984
return -1;
19931985
}
19941986
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

src/crypto/crypto_pbkdf2.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace node {
1111

12+
using ncrypto::Digest;
1213
using v8::FunctionCallbackInfo;
1314
using v8::Int32;
1415
using v8::JustVoid;
@@ -100,8 +101,8 @@ Maybe<void> PBKDF2Traits::AdditionalConfig(
100101
}
101102

102103
Utf8Value name(args.GetIsolate(), args[offset + 4]);
103-
params->digest = ncrypto::getDigestByName(name.ToStringView());
104-
if (params->digest == nullptr) [[unlikely]] {
104+
params->digest = Digest::FromName(name.ToStringView());
105+
if (!params->digest) [[unlikely]] {
105106
THROW_ERR_CRYPTO_INVALID_DIGEST(env, "Invalid digest: %s", *name);
106107
return Nothing<void>();
107108
}

src/crypto/crypto_pbkdf2.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct PBKDF2Config final : public MemoryRetainer {
3030
ByteSource salt;
3131
int32_t iterations;
3232
int32_t length;
33-
const EVP_MD* digest = nullptr;
33+
ncrypto::Digest digest;
3434

3535
PBKDF2Config() = default;
3636

0 commit comments

Comments
 (0)