Files
node/src/crypto/crypto_context.h
T
Filip Skokan a2cd8aa883 crypto,https,tls: end OpenSSL engine support
OpenSSL removed support for engines in version 4. Remove the Node.js
APIs, constants, native bindings, and implementation that depend on
ENGINE.

Keep recognizing the former TLS and HTTPS engine options so their use
fails explicitly instead of appearing to work while being ignored.

Move DEP0183 directly from Documentation-only to End-of-Life after
reverting its unreleased Runtime deprecation.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
Assisted-by: Codex
PR-URL: https://github.com/nodejs/node/pull/64777
Fixes: https://github.com/nodejs/node/issues/56733
Refs: https://github.com/nodejs/node/pull/64211
Refs: https://github.com/nodejs/node/pull/63966
Refs: https://github.com/nodejs/node/pull/53329
Refs: https://github.com/nodejs/node/pull/48950
Refs: https://github.com/nodejs/node/issues/45465
Refs: https://github.com/nodejs/node/issues/42827
Refs: https://github.com/nodejs/node/issues/47076
Refs: https://github.com/nodejs/node/pull/62862
Refs: https://github.com/nodejs/node/pull/38512
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
2026-10-25 22:36:38 +01:00

213 lines
8.1 KiB
C++

#ifndef SRC_CRYPTO_CRYPTO_CONTEXT_H_
#define SRC_CRYPTO_CRYPTO_CONTEXT_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "base_object.h"
#include "crypto/crypto_keys.h"
#include "crypto/crypto_util.h"
#include "env.h"
#include "memory_tracker.h"
#include "v8.h"
#ifdef NODE_OPENSSL_HAS_CERT_COMP
#include <vector>
#endif
namespace node {
namespace crypto {
// A maxVersion of 0 means "any", but OpenSSL may support TLS versions that
// Node.js doesn't, so pin the max to what we do support.
constexpr int kMaxSupportedVersion = TLS1_3_VERSION;
void GetRootCertificates(
const v8::FunctionCallbackInfo<v8::Value>& args);
X509_STORE* NewRootCertStore(Environment* env);
X509_STORE* GetOrCreateRootCertStore(Environment* env);
// Installs the certificate verification callback that applies the SPKI
// blocklist (and, on OpenSSL 4.1+, the CN name-constraint handling) to every
// chain verified through `ctx`. Must be called for every SSL_CTX Node.js
// creates, since SSL_CTX_set_cert_verify_callback replaces any earlier hook.
void InstallCertVerifyCallback(SSL_CTX* ctx);
ncrypto::BIOPointer LoadBIO(Environment* env, v8::Local<v8::Value> v);
class SecureContext final : public BaseObject {
public:
using GetSessionCb = SSL_SESSION* (*)(SSL*, const unsigned char*, int, int*);
using KeylogCb = void (*)(const SSL*, const char*);
using NewSessionCb = int (*)(SSL*, SSL_SESSION*);
using SelectSNIContextCb = int (*)(SSL*, int*, void*);
~SecureContext() override;
static bool HasInstance(Environment* env, const v8::Local<v8::Value>& value);
static v8::Local<v8::FunctionTemplate> GetConstructorTemplate(
Environment* env);
static void Initialize(Environment* env, v8::Local<v8::Object> target);
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static SecureContext* Create(Environment* env);
const ncrypto::SSLCtxPointer& ctx() const { return ctx_; }
// Non-const ctx() that allows for non-default initialization of
// the SecureContext.
ncrypto::SSLCtxPointer& ctx() { return ctx_; }
#ifdef NODE_OPENSSL_HAS_CERT_COMP
bool HasCertCompression() const {
return cert_comp_prefs_len_ > 0;
}
int* CertCompPrefs() {
return cert_comp_prefs_;
}
size_t CertCompPrefsLen() const {
return cert_comp_prefs_len_;
}
struct CompressedCertData {
int algorithm;
std::vector<unsigned char> data;
size_t orig_length;
};
const std::vector<CompressedCertData>& CompressedCerts() const {
return compressed_certs_;
}
#endif
ncrypto::SSLPointer CreateSSL();
void SetGetSessionCallback(GetSessionCb cb);
void SetKeylogCallback(KeylogCb cb);
void SetNewSessionCallback(NewSessionCb cb);
void SetSelectSNIContextCallback(SelectSNIContextCb cb);
inline const ncrypto::X509Pointer& issuer() const { return issuer_; }
inline const ncrypto::X509Pointer& cert() const { return cert_; }
v8::Maybe<void> AddCert(Environment* env, ncrypto::BIOPointer&& bio);
v8::Maybe<void> SetCRL(Environment* env, const ncrypto::BIOPointer& bio);
v8::Maybe<void> UseKey(Environment* env, const KeyObjectData& key);
void SetCACert(const ncrypto::BIOPointer& bio);
void SetRootCerts();
void SetX509StoreFlag(unsigned long flags); // NOLINT(runtime/int)
X509_STORE* GetCertStoreOwnedByThisSecureContext();
void MemoryInfo(MemoryTracker* tracker) const override;
SET_MEMORY_INFO_NAME(SecureContext)
SET_SELF_SIZE(SecureContext)
static const int kMaxSessionSize = 10 * 1024;
// See TicketKeyCallback
static const int kTicketKeyReturnIndex = 0;
static const int kTicketKeyHMACIndex = 1;
static const int kTicketKeyAESIndex = 2;
static const int kTicketKeyNameIndex = 3;
static const int kTicketKeyIVIndex = 4;
protected:
// OpenSSL structures are opaque. Estimate SSL_CTX memory usage:
static const int64_t kExternalSize = 1024;
static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Init(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetKey(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetCert(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddCACert(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetAllowPartialTrustChain(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddCRL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddRootCerts(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetCipherSuites(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetCiphers(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSigalgs(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetECDHCurve(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetDHParam(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSessionIdContext(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetSessionTimeout(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetCertificateCompression(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetCertificateCompressionAlgorithms(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetMinProto(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetMaxProto(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetMinProto(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetMaxProto(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
static void LoadPKCS12(const v8::FunctionCallbackInfo<v8::Value>& args);
static void GetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetTicketKeys(const v8::FunctionCallbackInfo<v8::Value>& args);
static void EnableTicketKeyCallback(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void CtxGetter(const v8::FunctionCallbackInfo<v8::Value>& info);
template <bool primary>
static void GetCertificate(const v8::FunctionCallbackInfo<v8::Value>& args);
// Test-only hooks for the SPKI blocklist that every SSL_CTX applies
// during certificate verification. Reachable through
// internalBinding('crypto') with --expose-internals. The argument is the
// SHA-256 of a DER-encoded SubjectPublicKeyInfo.
static void AddBlockedSPKIForTesting(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void ClearBlockedSPKIsForTesting(
const v8::FunctionCallbackInfo<v8::Value>& args);
static int TicketKeyCallback(SSL* ssl,
unsigned char* name,
unsigned char* iv,
EVP_CIPHER_CTX* ectx,
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVP_MAC_CTX* hctx,
#elif NCRYPTO_USE_BORINGSSL
HMAC_CTX* hctx,
#endif
int enc);
static int TicketCompatibilityCallback(SSL* ssl,
unsigned char* name,
unsigned char* iv,
EVP_CIPHER_CTX* ectx,
#if NCRYPTO_USE_OPENSSL_PROVIDER
EVP_MAC_CTX* hctx,
#elif NCRYPTO_USE_BORINGSSL
HMAC_CTX* hctx,
#endif
int enc);
SecureContext(Environment* env, v8::Local<v8::Object> wrap);
void Reset();
private:
ncrypto::SSLCtxPointer ctx_;
ncrypto::X509Pointer cert_;
ncrypto::X509Pointer issuer_;
// Non-owning cache for SSL_CTX_get_cert_store(ctx_.get())
X509_STORE* own_cert_store_cache_ = nullptr;
unsigned char ticket_key_name_[16];
unsigned char ticket_key_aes_[16];
unsigned char ticket_key_hmac_[16];
#ifdef NODE_OPENSSL_HAS_CERT_COMP
int cert_comp_prefs_[TLSEXT_comp_cert_limit] = {};
size_t cert_comp_prefs_len_ = 0;
std::vector<CompressedCertData> compressed_certs_;
#endif
};
} // namespace crypto
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_CRYPTO_CRYPTO_CONTEXT_H_