• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
4 #if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
5 
6 #include <base_object.h>
7 #include <crypto/crypto_context.h>
8 #include <crypto/crypto_keys.h>
9 #include <memory_tracker.h>
10 #include <ngtcp2/ngtcp2_crypto.h>
11 #include "bindingdata.h"
12 #include "data.h"
13 #include "sessionticket.h"
14 
15 namespace node {
16 namespace quic {
17 
18 class Session;
19 
20 // Every QUIC Session has exactly one TLSContext that maintains the state
21 // of the TLS handshake and negotiated cipher keys after the handshake has
22 // been completed. It is separated out from the main Session class only as a
23 // convenience to help make the code more maintainable and understandable.
24 class TLSContext final : public MemoryRetainer {
25  public:
26   static constexpr auto DEFAULT_CIPHERS = "TLS_AES_128_GCM_SHA256:"
27                                           "TLS_AES_256_GCM_SHA384:"
28                                           "TLS_CHACHA20_POLY1305_"
29                                           "SHA256:TLS_AES_128_CCM_SHA256";
30   static constexpr auto DEFAULT_GROUPS = "X25519:P-256:P-384:P-521";
31 
32   static inline const TLSContext& From(const SSL* ssl);
33   static inline TLSContext& From(SSL* ssl);
34 
35   struct Options final : public MemoryRetainer {
36     // The protocol identifier to be used by this Session.
37     std::string alpn = NGHTTP3_ALPN_H3;
38 
39     // The SNI hostname to be used. This is used only by client Sessions to
40     // identify the SNI host in the TLS client hello message.
41     std::string hostname = "";
42 
43     // When true, TLS keylog data will be emitted to the JavaScript session.
44     bool keylog = false;
45 
46     // When set, the peer certificate is verified against the list of supplied
47     // CAs. If verification fails, the connection will be refused.
48     bool reject_unauthorized = true;
49 
50     // When set, enables TLS tracing for the session. This should only be used
51     // for debugging.
52     bool enable_tls_trace = false;
53 
54     // Options only used by server sessions:
55 
56     // When set, instructs the server session to request a client authentication
57     // certificate.
58     bool request_peer_certificate = false;
59 
60     // Options only used by client sessions:
61 
62     // When set, instructs the client session to verify the hostname default.
63     // This is required by QUIC and enabled by default. We allow disabling it
64     // only for debugging.
65     bool verify_hostname_identity = true;
66 
67     // The TLS session ID context (only used on the server)
68     std::string session_id_ctx = "Node.js QUIC Server";
69 
70     // TLS cipher suite
71     std::string ciphers = DEFAULT_CIPHERS;
72 
73     // TLS groups
74     std::string groups = DEFAULT_GROUPS;
75 
76     // The TLS private key to use for this session.
77     std::vector<std::shared_ptr<crypto::KeyObjectData>> keys;
78 
79     // Collection of certificates to use for this session.
80     std::vector<Store> certs;
81 
82     // Optional certificate authority overrides to use.
83     std::vector<Store> ca;
84 
85     // Optional certificate revocation lists to use.
86     std::vector<Store> crl;
87 
88     void MemoryInfo(MemoryTracker* tracker) const override;
89     SET_MEMORY_INFO_NAME(CryptoContext::Options)
90     SET_SELF_SIZE(Options)
91 
92     static v8::Maybe<const Options> From(Environment* env,
93                                          v8::Local<v8::Value> value);
94   };
95 
96   static const Options kDefaultOptions;
97 
98   TLSContext(Environment* env,
99              Side side,
100              Session* session,
101              const Options& options);
102   TLSContext(const TLSContext&) = delete;
103   TLSContext(TLSContext&&) = delete;
104   TLSContext& operator=(const TLSContext&) = delete;
105   TLSContext& operator=(TLSContext&&) = delete;
106 
107   // Start the TLS handshake.
108   void Start();
109 
110   // TLS Keylogging is enabled per-Session by attaching a handler to the
111   // "keylog" event. Each keylog line is emitted to JavaScript where it can be
112   // routed to whatever destination makes sense. Typically, this will be to a
113   // keylog file that can be consumed by tools like Wireshark to intercept and
114   // decrypt QUIC network traffic.
115   void Keylog(const char* line) const;
116 
117   // Called when a chunk of peer TLS handshake data is received. For every
118   // chunk, we move the TLS handshake further along until it is complete.
119   int Receive(ngtcp2_crypto_level crypto_level,
120               uint64_t offset,
121               const ngtcp2_vec& vec);
122 
123   v8::MaybeLocal<v8::Object> cert(Environment* env) const;
124   v8::MaybeLocal<v8::Object> peer_cert(Environment* env) const;
125   v8::MaybeLocal<v8::Value> cipher_name(Environment* env) const;
126   v8::MaybeLocal<v8::Value> cipher_version(Environment* env) const;
127   v8::MaybeLocal<v8::Object> ephemeral_key(Environment* env) const;
128 
129   // The SNI servername negotiated for the session
130   const std::string_view servername() const;
131 
132   // The ALPN (protocol name) negotiated for the session
133   const std::string_view alpn() const;
134 
135   // Triggers key update to begin. This will fail and return false if either a
136   // previous key update is in progress and has not been confirmed or if the
137   // initial handshake has not yet been confirmed.
138   bool InitiateKeyUpdate();
139 
140   int VerifyPeerIdentity();
141 
142   Side side() const;
143   const Options& options() const;
144 
145   int OnNewSession(SSL_SESSION* session);
146 
147   void MaybeSetEarlySession(const SessionTicket& sessionTicket);
148   bool early_data_was_accepted() const;
149 
150   void MemoryInfo(MemoryTracker* tracker) const override;
151   SET_MEMORY_INFO_NAME(CryptoContext)
152   SET_SELF_SIZE(TLSContext)
153 
154  private:
155   static ngtcp2_conn* getConnection(ngtcp2_crypto_conn_ref* ref);
156   ngtcp2_crypto_conn_ref conn_ref_;
157 
158   Side side_;
159   Environment* env_;
160   Session* session_;
161   const Options options_;
162   BaseObjectPtr<crypto::SecureContext> secure_context_;
163   crypto::SSLPointer ssl_;
164   crypto::BIOPointer bio_trace_;
165 
166   bool in_key_update_ = false;
167   bool early_data_ = false;
168 
169   friend class Session;
170 };
171 
172 }  // namespace quic
173 }  // namespace node
174 
175 #endif  // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
176 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
177