From e79a7aa64b276317dd8d8667082603d7d5fc2d94 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 2 Jan 2025 08:56:43 -0800 Subject: [PATCH] src: move SSLCtxPointer impl to ncrypto --- deps/ncrypto/ncrypto.cc | 42 ++++++++++++++++++++++++++++++++++++ deps/ncrypto/ncrypto.h | 34 ++++++++++++++++++++++++++++- src/crypto/crypto_cipher.cc | 2 +- src/crypto/crypto_common.cc | 2 +- src/crypto/crypto_context.cc | 2 +- src/crypto/crypto_tls.cc | 3 +-- src/quic/tlscontext.cc | 4 ++-- 7 files changed, 81 insertions(+), 8 deletions(-) diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index 575be4fee3fd6c..26285db46d50a7 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -2371,4 +2371,46 @@ EVPKeyPointer SSLPointer::getPeerTempKey() const { if (!SSL_get_peer_tmp_key(get(), &raw_key)) return {}; return EVPKeyPointer(raw_key); } + +SSLCtxPointer::SSLCtxPointer(SSL_CTX* ctx) : ctx_(ctx) {} + +SSLCtxPointer::SSLCtxPointer(SSLCtxPointer&& other) noexcept + : ctx_(other.release()) {} + +SSLCtxPointer& SSLCtxPointer::operator=(SSLCtxPointer&& other) noexcept { + if (this == &other) return *this; + this->~SSLCtxPointer(); + return *new (this) SSLCtxPointer(std::move(other)); +} + +SSLCtxPointer::~SSLCtxPointer() { reset(); } + +void SSLCtxPointer::reset(SSL_CTX* ctx) { + ctx_.reset(ctx); +} + +void SSLCtxPointer::reset(const SSL_METHOD* method) { + ctx_.reset(SSL_CTX_new(method)); +} + +SSL_CTX* SSLCtxPointer::release() { + return ctx_.release(); +} + +SSLCtxPointer SSLCtxPointer::NewServer() { + return SSLCtxPointer(SSL_CTX_new(TLS_server_method())); +} + +SSLCtxPointer SSLCtxPointer::NewClient() { + return SSLCtxPointer(SSL_CTX_new(TLS_client_method())); +} + +SSLCtxPointer SSLCtxPointer::New(const SSL_METHOD* method) { + return SSLCtxPointer(SSL_CTX_new(method)); +} + +bool SSLCtxPointer::setGroups(const char* groups) { + return SSL_CTX_set1_groups_list(get(), groups) == 1; +} + } // namespace ncrypto diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h index 9e3b86334cdbeb..d404ca86407bd9 100644 --- a/deps/ncrypto/ncrypto.h +++ b/deps/ncrypto/ncrypto.h @@ -211,7 +211,6 @@ using HMACCtxPointer = DeleteFnPtr; using NetscapeSPKIPointer = DeleteFnPtr; using PKCS8Pointer = DeleteFnPtr; using RSAPointer = DeleteFnPtr; -using SSLCtxPointer = DeleteFnPtr; using SSLSessionPointer = DeleteFnPtr; struct StackOfXASN1Deleter { @@ -582,6 +581,39 @@ using StackOfX509 = std::unique_ptr; class X509Pointer; class X509View; +class SSLCtxPointer final { + public: + SSLCtxPointer() = default; + explicit SSLCtxPointer(SSL_CTX* ctx); + SSLCtxPointer(SSLCtxPointer&& other) noexcept; + SSLCtxPointer& operator=(SSLCtxPointer&& other) noexcept; + NCRYPTO_DISALLOW_COPY(SSLCtxPointer) + ~SSLCtxPointer(); + + inline bool operator==(std::nullptr_t) const noexcept { + return ctx_ == nullptr; + } + inline operator bool() const { return ctx_ != nullptr; } + inline SSL_CTX* get() const { return ctx_.get(); } + void reset(SSL_CTX* ctx = nullptr); + void reset(const SSL_METHOD* method); + SSL_CTX* release(); + + bool setGroups(const char* groups); + void setStatusCallback(auto callback) { + if (!ctx_) return; + SSL_CTX_set_tlsext_status_cb(get(), callback); + SSL_CTX_set_tlsext_status_arg(get(), nullptr); + } + + static SSLCtxPointer NewServer(); + static SSLCtxPointer NewClient(); + static SSLCtxPointer New(const SSL_METHOD* method = TLS_method()); + + private: + DeleteFnPtr ctx_; +}; + class SSLPointer final { public: SSLPointer() = default; diff --git a/src/crypto/crypto_cipher.cc b/src/crypto/crypto_cipher.cc index 075ff3c008fb4b..7bacc6c684028f 100644 --- a/src/crypto/crypto_cipher.cc +++ b/src/crypto/crypto_cipher.cc @@ -198,7 +198,7 @@ void GetCipherInfo(const FunctionCallbackInfo& args) { void CipherBase::GetSSLCiphers(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - SSLCtxPointer ctx(SSL_CTX_new(TLS_method())); + auto ctx = SSLCtxPointer::New(); if (!ctx) { return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new"); } diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc index c30c8947b934fd..f7e5f800cd9900 100644 --- a/src/crypto/crypto_common.cc +++ b/src/crypto/crypto_common.cc @@ -58,7 +58,7 @@ bool UseSNIContext( } bool SetGroups(SecureContext* sc, const char* groups) { - return SSL_CTX_set1_groups_list(sc->ctx().get(), groups) == 1; + return sc->ctx().setGroups(groups); } MaybeLocal GetValidationErrorReason(Environment* env, int err) { diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc index db6f437759c3ec..fa96b8d7a51d46 100644 --- a/src/crypto/crypto_context.cc +++ b/src/crypto/crypto_context.cc @@ -551,7 +551,7 @@ void SecureContext::Init(const FunctionCallbackInfo& args) { } } - sc->ctx_.reset(SSL_CTX_new(method)); + sc->ctx_.reset(method); if (!sc->ctx_) { return ThrowCryptoError(env, ERR_get_error(), "SSL_CTX_new"); } diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index dbc50878b9860c..51ed6466c9391a 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -358,8 +358,7 @@ int TLSExtStatusCallback(SSL* s, void* arg) { void ConfigureSecureContext(SecureContext* sc) { // OCSP stapling - SSL_CTX_set_tlsext_status_cb(sc->ctx().get(), TLSExtStatusCallback); - SSL_CTX_set_tlsext_status_arg(sc->ctx().get(), nullptr); + sc->ctx().setStatusCallback(TLSExtStatusCallback); } inline bool Set( diff --git a/src/quic/tlscontext.cc b/src/quic/tlscontext.cc index 916d6f0efb4c7e..8e2995589c9116 100644 --- a/src/quic/tlscontext.cc +++ b/src/quic/tlscontext.cc @@ -245,7 +245,7 @@ crypto::SSLCtxPointer TLSContext::Initialize() { switch (side_) { case Side::SERVER: { static constexpr unsigned char kSidCtx[] = "Node.js QUIC Server"; - ctx.reset(SSL_CTX_new(TLS_server_method())); + ctx = crypto::SSLCtxPointer::NewServer(); CHECK_EQ(ngtcp2_crypto_quictls_configure_server_context(ctx.get()), 0); CHECK_EQ(SSL_CTX_set_max_early_data(ctx.get(), UINT32_MAX), 1); SSL_CTX_set_options(ctx.get(), @@ -276,7 +276,7 @@ crypto::SSLCtxPointer TLSContext::Initialize() { break; } case Side::CLIENT: { - ctx.reset(SSL_CTX_new(TLS_client_method())); + ctx = crypto::SSLCtxPointer::NewClient(); CHECK_EQ(ngtcp2_crypto_quictls_configure_client_context(ctx.get()), 0); SSL_CTX_set_session_cache_mode(