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