Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f22a969

Browse files
committedJan 7, 2025·
src: move CipherCtx methods to ncrypto
1 parent 3dacb82 commit f22a969

File tree

6 files changed

+301
-163
lines changed

6 files changed

+301
-163
lines changed
 

‎deps/ncrypto/ncrypto.cc

+130-21
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ int BignumPointer::isPrime(int nchecks,
321321
return -1;
322322
BN_GENCB_set(
323323
cb.get(),
324+
// TODO(@jasnell): This could be refactored to allow inlining.
325+
// Not too important right now tho.
324326
[](int a, int b, BN_GENCB* ctx) mutable -> int {
325327
PrimeCheckCallback& ptr =
326328
*static_cast<PrimeCheckCallback*>(BN_GENCB_get_arg(ctx));
@@ -374,6 +376,7 @@ bool BignumPointer::generate(const PrimeConfig& params,
374376
BignumPointer BignumPointer::NewSub(const BignumPointer& a,
375377
const BignumPointer& b) {
376378
BignumPointer res = New();
379+
if (!res) return {};
377380
if (!BN_sub(res.get(), a.get(), b.get())) {
378381
return {};
379382
}
@@ -382,6 +385,7 @@ BignumPointer BignumPointer::NewSub(const BignumPointer& a,
382385

383386
BignumPointer BignumPointer::NewLShift(size_t length) {
384387
BignumPointer res = New();
388+
if (!res) return {};
385389
if (!BN_lshift(res.get(), One(), length)) {
386390
return {};
387391
}
@@ -1192,8 +1196,8 @@ std::string_view X509Pointer::ErrorCode(int32_t err) { // NOLINT(runtime/int)
11921196
return "UNSPECIFIED";
11931197
}
11941198

1195-
std::string_view X509Pointer::ErrorReason(int32_t err) {
1196-
if (err == X509_V_OK) return "";
1199+
std::optional<std::string_view> X509Pointer::ErrorReason(int32_t err) {
1200+
if (err == X509_V_OK) return std::nullopt;
11971201
return X509_verify_cert_error_string(err);
11981202
}
11991203

@@ -2235,11 +2239,12 @@ void SSLPointer::getCiphers(
22352239
// document them, but since there are only 5, easier to just add them manually
22362240
// and not have to explain their absence in the API docs. They are lower-cased
22372241
// because the docs say they will be.
2238-
static const char* TLS13_CIPHERS[] = {"tls_aes_256_gcm_sha384",
2239-
"tls_chacha20_poly1305_sha256",
2240-
"tls_aes_128_gcm_sha256",
2241-
"tls_aes_128_ccm_8_sha256",
2242-
"tls_aes_128_ccm_sha256"};
2242+
static constexpr const char* TLS13_CIPHERS[] = {
2243+
"tls_aes_256_gcm_sha384",
2244+
"tls_chacha20_poly1305_sha256",
2245+
"tls_aes_128_gcm_sha256",
2246+
"tls_aes_128_ccm_8_sha256",
2247+
"tls_aes_128_ccm_sha256"};
22432248

22442249
const int n = sk_SSL_CIPHER_num(ciphers);
22452250

@@ -2249,8 +2254,7 @@ void SSLPointer::getCiphers(
22492254
}
22502255

22512256
for (unsigned i = 0; i < 5; ++i) {
2252-
const char* name = TLS13_CIPHERS[i];
2253-
cb(name);
2257+
cb(TLS13_CIPHERS[i]);
22542258
}
22552259
}
22562260

@@ -2265,7 +2269,6 @@ bool SSLPointer::setSniContext(const SSLCtxPointer& ctx) const {
22652269
if (!x509) return false;
22662270
EVP_PKEY* pkey = SSL_CTX_get0_privatekey(ctx.get());
22672271
STACK_OF(X509) * chain;
2268-
22692272
int err = SSL_CTX_get0_chain_certs(ctx.get(), &chain);
22702273
if (err == 1) err = SSL_use_certificate(get(), x509);
22712274
if (err == 1) err = SSL_use_PrivateKey(get(), pkey);
@@ -2294,7 +2297,7 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
22942297
}
22952298

22962299
const std::string_view SSLPointer::getClientHelloAlpn() const {
2297-
if (ssl_ == nullptr) return std::string_view();
2300+
if (ssl_ == nullptr) return {};
22982301
const unsigned char* buf;
22992302
size_t len;
23002303
size_t rem;
@@ -2305,34 +2308,34 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
23052308
&buf,
23062309
&rem) ||
23072310
rem < 2) {
2308-
return nullptr;
2311+
return {};
23092312
}
23102313

23112314
len = (buf[0] << 8) | buf[1];
2312-
if (len + 2 != rem) return nullptr;
2315+
if (len + 2 != rem) return {};
23132316
return reinterpret_cast<const char*>(buf + 3);
23142317
}
23152318

23162319
const std::string_view SSLPointer::getClientHelloServerName() const {
2317-
if (ssl_ == nullptr) return std::string_view();
2320+
if (ssl_ == nullptr) return {};
23182321
const unsigned char* buf;
23192322
size_t len;
23202323
size_t rem;
23212324

23222325
if (!SSL_client_hello_get0_ext(get(), TLSEXT_TYPE_server_name, &buf, &rem) ||
23232326
rem <= 2) {
2324-
return nullptr;
2327+
return {};
23252328
}
23262329

23272330
len = (*buf << 8) | *(buf + 1);
2328-
if (len + 2 != rem) return nullptr;
2331+
if (len + 2 != rem) return {};
23292332
rem = len;
23302333

2331-
if (rem == 0 || *(buf + 2) != TLSEXT_NAMETYPE_host_name) return nullptr;
2334+
if (rem == 0 || *(buf + 2) != TLSEXT_NAMETYPE_host_name) return {};
23322335
rem--;
2333-
if (rem <= 2) return nullptr;
2336+
if (rem <= 2) return {};
23342337
len = (*(buf + 3) << 8) | *(buf + 4);
2335-
if (len + 2 > rem) return nullptr;
2338+
if (len + 2 > rem) return {};
23362339
return reinterpret_cast<const char*>(buf + 5);
23372340
}
23382341

@@ -2453,7 +2456,7 @@ int Cipher::getNid() const {
24532456
return EVP_CIPHER_nid(cipher_);
24542457
}
24552458

2456-
const std::string_view Cipher::getModeLabel() const {
2459+
std::string_view Cipher::getModeLabel() const {
24572460
if (!cipher_) return {};
24582461
switch (getMode()) {
24592462
case EVP_CIPH_CCM_MODE:
@@ -2482,7 +2485,7 @@ const std::string_view Cipher::getModeLabel() const {
24822485
return "{unknown}";
24832486
}
24842487

2485-
const std::string_view Cipher::getName() const {
2488+
std::string_view Cipher::getName() const {
24862489
if (!cipher_) return {};
24872490
// OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
24882491
// EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
@@ -2504,4 +2507,110 @@ bool Cipher::isSupportedAuthenticatedMode() const {
25042507
}
25052508
}
25062509

2510+
// ============================================================================
2511+
2512+
CipherCtxPointer CipherCtxPointer::New() {
2513+
auto ret = CipherCtxPointer(EVP_CIPHER_CTX_new());
2514+
if (!ret) return {};
2515+
EVP_CIPHER_CTX_init(ret.get());
2516+
return ret;
2517+
}
2518+
2519+
CipherCtxPointer::CipherCtxPointer(EVP_CIPHER_CTX* ctx) : ctx_(ctx) {}
2520+
2521+
CipherCtxPointer::CipherCtxPointer(CipherCtxPointer&& other) noexcept
2522+
: ctx_(other.release()) {}
2523+
2524+
CipherCtxPointer& CipherCtxPointer::operator=(
2525+
CipherCtxPointer&& other) noexcept {
2526+
if (this == &other) return *this;
2527+
this->~CipherCtxPointer();
2528+
return *new (this) CipherCtxPointer(std::move(other));
2529+
}
2530+
2531+
CipherCtxPointer::~CipherCtxPointer() {
2532+
reset();
2533+
}
2534+
2535+
void CipherCtxPointer::reset(EVP_CIPHER_CTX* ctx) {
2536+
ctx_.reset(ctx);
2537+
}
2538+
2539+
EVP_CIPHER_CTX* CipherCtxPointer::release() {
2540+
return ctx_.release();
2541+
}
2542+
2543+
void CipherCtxPointer::setFlags(int flags) {
2544+
if (!ctx_) return;
2545+
EVP_CIPHER_CTX_set_flags(ctx_.get(), flags);
2546+
}
2547+
2548+
bool CipherCtxPointer::setKeyLength(size_t length) {
2549+
if (!ctx_) return false;
2550+
return EVP_CIPHER_CTX_set_key_length(ctx_.get(), length);
2551+
}
2552+
2553+
bool CipherCtxPointer::setIvLength(size_t length) {
2554+
if (!ctx_) return false;
2555+
return EVP_CIPHER_CTX_ctrl(
2556+
ctx_.get(), EVP_CTRL_AEAD_SET_IVLEN, length, nullptr);
2557+
}
2558+
2559+
bool CipherCtxPointer::setAeadTag(const Buffer<const char>& tag) {
2560+
if (!ctx_) return false;
2561+
return EVP_CIPHER_CTX_ctrl(
2562+
ctx_.get(), EVP_CTRL_AEAD_SET_TAG, tag.len, const_cast<char*>(tag.data));
2563+
}
2564+
2565+
bool CipherCtxPointer::setAeadTagLength(size_t length) {
2566+
if (!ctx_) return false;
2567+
return EVP_CIPHER_CTX_ctrl(
2568+
ctx_.get(), EVP_CTRL_AEAD_SET_TAG, length, nullptr);
2569+
}
2570+
2571+
bool CipherCtxPointer::setPadding(bool padding) {
2572+
if (!ctx_) return false;
2573+
return EVP_CIPHER_CTX_set_padding(ctx_.get(), padding);
2574+
}
2575+
2576+
int CipherCtxPointer::getBlockSize() const {
2577+
if (!ctx_) return 0;
2578+
return EVP_CIPHER_CTX_block_size(ctx_.get());
2579+
}
2580+
2581+
int CipherCtxPointer::getMode() const {
2582+
if (!ctx_) return 0;
2583+
return EVP_CIPHER_CTX_mode(ctx_.get());
2584+
}
2585+
2586+
int CipherCtxPointer::getNid() const {
2587+
if (!ctx_) return 0;
2588+
return EVP_CIPHER_CTX_nid(ctx_.get());
2589+
}
2590+
2591+
bool CipherCtxPointer::init(const Cipher& cipher,
2592+
bool encrypt,
2593+
const unsigned char* key,
2594+
const unsigned char* iv) {
2595+
if (!ctx_) return false;
2596+
return EVP_CipherInit_ex(
2597+
ctx_.get(), cipher, nullptr, key, iv, encrypt ? 1 : 0) == 1;
2598+
}
2599+
2600+
bool CipherCtxPointer::update(const Buffer<const unsigned char>& in,
2601+
unsigned char* out,
2602+
int* out_len,
2603+
bool finalize) {
2604+
if (!ctx_) return false;
2605+
if (!finalize) {
2606+
return EVP_CipherUpdate(ctx_.get(), out, out_len, in.data, in.len) == 1;
2607+
}
2608+
return EVP_CipherFinal_ex(ctx_.get(), out, out_len) == 1;
2609+
}
2610+
2611+
bool CipherCtxPointer::getAeadTag(size_t len, unsigned char* out) {
2612+
if (!ctx_) return false;
2613+
return EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_AEAD_GET_TAG, len, out);
2614+
}
2615+
25072616
} // namespace ncrypto

‎deps/ncrypto/ncrypto.h

+50-4
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
197197

198198
using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
199199
using BignumGenCallbackPointer = DeleteFnPtr<BN_GENCB, BN_GENCB_free>;
200-
using CipherCtxPointer = DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free>;
201200
using DSAPointer = DeleteFnPtr<DSA, DSA_free>;
202201
using DSASigPointer = DeleteFnPtr<DSA_SIG, DSA_SIG_free>;
203202
using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;
@@ -213,6 +212,8 @@ using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
213212
using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
214213
using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;
215214

215+
class CipherCtxPointer;
216+
216217
struct StackOfXASN1Deleter {
217218
void operator()(STACK_OF(ASN1_OBJECT) * p) const {
218219
sk_ASN1_OBJECT_pop_free(p, ASN1_OBJECT_free);
@@ -248,8 +249,8 @@ class Cipher final {
248249
int getIvLength() const;
249250
int getKeyLength() const;
250251
int getBlockSize() const;
251-
const std::string_view getModeLabel() const;
252-
const std::string_view getName() const;
252+
std::string_view getModeLabel() const;
253+
std::string_view getName() const;
253254

254255
bool isSupportedAuthenticatedMode() const;
255256

@@ -425,6 +426,51 @@ class BignumPointer final {
425426
static bool defaultPrimeCheckCallback(int, int) { return 1; }
426427
};
427428

429+
class CipherCtxPointer final {
430+
public:
431+
static CipherCtxPointer New();
432+
433+
CipherCtxPointer() = default;
434+
explicit CipherCtxPointer(EVP_CIPHER_CTX* ctx);
435+
CipherCtxPointer(CipherCtxPointer&& other) noexcept;
436+
CipherCtxPointer& operator=(CipherCtxPointer&& other) noexcept;
437+
NCRYPTO_DISALLOW_COPY(CipherCtxPointer)
438+
~CipherCtxPointer();
439+
440+
inline bool operator==(std::nullptr_t) const noexcept {
441+
return ctx_ == nullptr;
442+
}
443+
inline operator bool() const { return ctx_ != nullptr; }
444+
inline EVP_CIPHER_CTX* get() const { return ctx_.get(); }
445+
inline operator EVP_CIPHER_CTX*() const { return ctx_.get(); }
446+
void reset(EVP_CIPHER_CTX* ctx = nullptr);
447+
EVP_CIPHER_CTX* release();
448+
449+
void setFlags(int flags);
450+
bool setKeyLength(size_t length);
451+
bool setIvLength(size_t length);
452+
bool setAeadTag(const Buffer<const char>& tag);
453+
bool setAeadTagLength(size_t length);
454+
bool setPadding(bool padding);
455+
bool init(const Cipher& cipher,
456+
bool encrypt,
457+
const unsigned char* key = nullptr,
458+
const unsigned char* iv = nullptr);
459+
460+
int getBlockSize() const;
461+
int getMode() const;
462+
int getNid() const;
463+
464+
bool update(const Buffer<const unsigned char>& in,
465+
unsigned char* out,
466+
int* out_len,
467+
bool finalize = false);
468+
bool getAeadTag(size_t len, unsigned char* out);
469+
470+
private:
471+
DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_;
472+
};
473+
428474
class EVPKeyPointer final {
429475
public:
430476
static EVPKeyPointer New();
@@ -772,7 +818,7 @@ class X509Pointer final {
772818
operator X509View() const { return view(); }
773819

774820
static std::string_view ErrorCode(int32_t err);
775-
static std::string_view ErrorReason(int32_t err);
821+
static std::optional<std::string_view> ErrorReason(int32_t err);
776822

777823
private:
778824
DeleteFnPtr<X509, X509_free> cert_;

0 commit comments

Comments
 (0)
Please sign in to comment.