xref: /third_party/node/src/quic/tlscontext.h (revision 1cb0ef41)
11cb0ef41Sopenharmony_ci#pragma once
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
41cb0ef41Sopenharmony_ci#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ci#include <base_object.h>
71cb0ef41Sopenharmony_ci#include <crypto/crypto_context.h>
81cb0ef41Sopenharmony_ci#include <crypto/crypto_keys.h>
91cb0ef41Sopenharmony_ci#include <memory_tracker.h>
101cb0ef41Sopenharmony_ci#include <ngtcp2/ngtcp2_crypto.h>
111cb0ef41Sopenharmony_ci#include "bindingdata.h"
121cb0ef41Sopenharmony_ci#include "data.h"
131cb0ef41Sopenharmony_ci#include "sessionticket.h"
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_cinamespace node {
161cb0ef41Sopenharmony_cinamespace quic {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciclass Session;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// Every QUIC Session has exactly one TLSContext that maintains the state
211cb0ef41Sopenharmony_ci// of the TLS handshake and negotiated cipher keys after the handshake has
221cb0ef41Sopenharmony_ci// been completed. It is separated out from the main Session class only as a
231cb0ef41Sopenharmony_ci// convenience to help make the code more maintainable and understandable.
241cb0ef41Sopenharmony_ciclass TLSContext final : public MemoryRetainer {
251cb0ef41Sopenharmony_ci public:
261cb0ef41Sopenharmony_ci  static constexpr auto DEFAULT_CIPHERS = "TLS_AES_128_GCM_SHA256:"
271cb0ef41Sopenharmony_ci                                          "TLS_AES_256_GCM_SHA384:"
281cb0ef41Sopenharmony_ci                                          "TLS_CHACHA20_POLY1305_"
291cb0ef41Sopenharmony_ci                                          "SHA256:TLS_AES_128_CCM_SHA256";
301cb0ef41Sopenharmony_ci  static constexpr auto DEFAULT_GROUPS = "X25519:P-256:P-384:P-521";
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  static inline const TLSContext& From(const SSL* ssl);
331cb0ef41Sopenharmony_ci  static inline TLSContext& From(SSL* ssl);
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  struct Options final : public MemoryRetainer {
361cb0ef41Sopenharmony_ci    // The protocol identifier to be used by this Session.
371cb0ef41Sopenharmony_ci    std::string alpn = NGHTTP3_ALPN_H3;
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci    // The SNI hostname to be used. This is used only by client Sessions to
401cb0ef41Sopenharmony_ci    // identify the SNI host in the TLS client hello message.
411cb0ef41Sopenharmony_ci    std::string hostname = "";
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci    // When true, TLS keylog data will be emitted to the JavaScript session.
441cb0ef41Sopenharmony_ci    bool keylog = false;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci    // When set, the peer certificate is verified against the list of supplied
471cb0ef41Sopenharmony_ci    // CAs. If verification fails, the connection will be refused.
481cb0ef41Sopenharmony_ci    bool reject_unauthorized = true;
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci    // When set, enables TLS tracing for the session. This should only be used
511cb0ef41Sopenharmony_ci    // for debugging.
521cb0ef41Sopenharmony_ci    bool enable_tls_trace = false;
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    // Options only used by server sessions:
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci    // When set, instructs the server session to request a client authentication
571cb0ef41Sopenharmony_ci    // certificate.
581cb0ef41Sopenharmony_ci    bool request_peer_certificate = false;
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci    // Options only used by client sessions:
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci    // When set, instructs the client session to verify the hostname default.
631cb0ef41Sopenharmony_ci    // This is required by QUIC and enabled by default. We allow disabling it
641cb0ef41Sopenharmony_ci    // only for debugging.
651cb0ef41Sopenharmony_ci    bool verify_hostname_identity = true;
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    // The TLS session ID context (only used on the server)
681cb0ef41Sopenharmony_ci    std::string session_id_ctx = "Node.js QUIC Server";
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci    // TLS cipher suite
711cb0ef41Sopenharmony_ci    std::string ciphers = DEFAULT_CIPHERS;
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci    // TLS groups
741cb0ef41Sopenharmony_ci    std::string groups = DEFAULT_GROUPS;
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci    // The TLS private key to use for this session.
771cb0ef41Sopenharmony_ci    std::vector<std::shared_ptr<crypto::KeyObjectData>> keys;
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci    // Collection of certificates to use for this session.
801cb0ef41Sopenharmony_ci    std::vector<Store> certs;
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci    // Optional certificate authority overrides to use.
831cb0ef41Sopenharmony_ci    std::vector<Store> ca;
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci    // Optional certificate revocation lists to use.
861cb0ef41Sopenharmony_ci    std::vector<Store> crl;
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci    void MemoryInfo(MemoryTracker* tracker) const override;
891cb0ef41Sopenharmony_ci    SET_MEMORY_INFO_NAME(CryptoContext::Options)
901cb0ef41Sopenharmony_ci    SET_SELF_SIZE(Options)
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci    static v8::Maybe<const Options> From(Environment* env,
931cb0ef41Sopenharmony_ci                                         v8::Local<v8::Value> value);
941cb0ef41Sopenharmony_ci  };
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci  static const Options kDefaultOptions;
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  TLSContext(Environment* env,
991cb0ef41Sopenharmony_ci             Side side,
1001cb0ef41Sopenharmony_ci             Session* session,
1011cb0ef41Sopenharmony_ci             const Options& options);
1021cb0ef41Sopenharmony_ci  TLSContext(const TLSContext&) = delete;
1031cb0ef41Sopenharmony_ci  TLSContext(TLSContext&&) = delete;
1041cb0ef41Sopenharmony_ci  TLSContext& operator=(const TLSContext&) = delete;
1051cb0ef41Sopenharmony_ci  TLSContext& operator=(TLSContext&&) = delete;
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  // Start the TLS handshake.
1081cb0ef41Sopenharmony_ci  void Start();
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci  // TLS Keylogging is enabled per-Session by attaching a handler to the
1111cb0ef41Sopenharmony_ci  // "keylog" event. Each keylog line is emitted to JavaScript where it can be
1121cb0ef41Sopenharmony_ci  // routed to whatever destination makes sense. Typically, this will be to a
1131cb0ef41Sopenharmony_ci  // keylog file that can be consumed by tools like Wireshark to intercept and
1141cb0ef41Sopenharmony_ci  // decrypt QUIC network traffic.
1151cb0ef41Sopenharmony_ci  void Keylog(const char* line) const;
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  // Called when a chunk of peer TLS handshake data is received. For every
1181cb0ef41Sopenharmony_ci  // chunk, we move the TLS handshake further along until it is complete.
1191cb0ef41Sopenharmony_ci  int Receive(ngtcp2_crypto_level crypto_level,
1201cb0ef41Sopenharmony_ci              uint64_t offset,
1211cb0ef41Sopenharmony_ci              const ngtcp2_vec& vec);
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Object> cert(Environment* env) const;
1241cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Object> peer_cert(Environment* env) const;
1251cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> cipher_name(Environment* env) const;
1261cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> cipher_version(Environment* env) const;
1271cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Object> ephemeral_key(Environment* env) const;
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  // The SNI servername negotiated for the session
1301cb0ef41Sopenharmony_ci  const std::string_view servername() const;
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci  // The ALPN (protocol name) negotiated for the session
1331cb0ef41Sopenharmony_ci  const std::string_view alpn() const;
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  // Triggers key update to begin. This will fail and return false if either a
1361cb0ef41Sopenharmony_ci  // previous key update is in progress and has not been confirmed or if the
1371cb0ef41Sopenharmony_ci  // initial handshake has not yet been confirmed.
1381cb0ef41Sopenharmony_ci  bool InitiateKeyUpdate();
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  int VerifyPeerIdentity();
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  Side side() const;
1431cb0ef41Sopenharmony_ci  const Options& options() const;
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  int OnNewSession(SSL_SESSION* session);
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  void MaybeSetEarlySession(const SessionTicket& sessionTicket);
1481cb0ef41Sopenharmony_ci  bool early_data_was_accepted() const;
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  void MemoryInfo(MemoryTracker* tracker) const override;
1511cb0ef41Sopenharmony_ci  SET_MEMORY_INFO_NAME(CryptoContext)
1521cb0ef41Sopenharmony_ci  SET_SELF_SIZE(TLSContext)
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci private:
1551cb0ef41Sopenharmony_ci  static ngtcp2_conn* getConnection(ngtcp2_crypto_conn_ref* ref);
1561cb0ef41Sopenharmony_ci  ngtcp2_crypto_conn_ref conn_ref_;
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  Side side_;
1591cb0ef41Sopenharmony_ci  Environment* env_;
1601cb0ef41Sopenharmony_ci  Session* session_;
1611cb0ef41Sopenharmony_ci  const Options options_;
1621cb0ef41Sopenharmony_ci  BaseObjectPtr<crypto::SecureContext> secure_context_;
1631cb0ef41Sopenharmony_ci  crypto::SSLPointer ssl_;
1641cb0ef41Sopenharmony_ci  crypto::BIOPointer bio_trace_;
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  bool in_key_update_ = false;
1671cb0ef41Sopenharmony_ci  bool early_data_ = false;
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  friend class Session;
1701cb0ef41Sopenharmony_ci};
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci}  // namespace quic
1731cb0ef41Sopenharmony_ci}  // namespace node
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci#endif  // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
1761cb0ef41Sopenharmony_ci#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
177