1 // Copyright (c) 2020 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_ 6 #define QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_ 7 8 #include <cstdint> 9 #include <memory> 10 #include <string> 11 #include <vector> 12 13 #include "absl/types/span.h" 14 #include "openssl/ssl.h" 15 #include "quiche/quic/core/frames/quic_ack_frequency_frame.h" 16 #include "quiche/quic/core/quic_framer.h" 17 #include "quiche/quic/core/quic_packets.h" 18 #include "quiche/quic/core/quic_stream_sequencer.h" 19 #include "quiche/quic/core/quic_types.h" 20 #include "quiche/quic/platform/api/quic_export.h" 21 22 namespace quic { 23 24 // Utility class that allows extracting information from a QUIC-TLS Client 25 // Hello. This class creates a QuicFramer to parse the packet, and implements 26 // QuicFramerVisitorInterface to access the frames parsed by the QuicFramer. It 27 // then uses a QuicStreamSequencer to reassemble the contents of the crypto 28 // stream, and implements QuicStreamSequencer::StreamInterface to access the 29 // reassembled data. 30 class QUICHE_EXPORT TlsChloExtractor 31 : public QuicFramerVisitorInterface, 32 public QuicStreamSequencer::StreamInterface { 33 public: 34 TlsChloExtractor(); 35 TlsChloExtractor(const TlsChloExtractor&) = delete; 36 TlsChloExtractor(TlsChloExtractor&&); 37 TlsChloExtractor& operator=(const TlsChloExtractor&) = delete; 38 TlsChloExtractor& operator=(TlsChloExtractor&&); 39 40 enum class State : uint8_t { 41 kInitial = 0, 42 kParsedFullSinglePacketChlo = 1, 43 kParsedFullMultiPacketChlo = 2, 44 kParsedPartialChloFragment = 3, 45 kUnrecoverableFailure = 4, 46 }; 47 state()48 State state() const { return state_; } alpns()49 std::vector<std::string> alpns() const { return alpns_; } server_name()50 std::string server_name() const { return server_name_; } resumption_attempted()51 bool resumption_attempted() const { return resumption_attempted_; } early_data_attempted()52 bool early_data_attempted() const { return early_data_attempted_; } supported_groups()53 const std::vector<uint16_t>& supported_groups() const { 54 return supported_groups_; 55 } client_hello_bytes()56 absl::Span<const uint8_t> client_hello_bytes() const { 57 return client_hello_bytes_; 58 } 59 60 // Converts |state| to a human-readable string suitable for logging. 61 static std::string StateToString(State state); 62 63 // Ingests |packet| and attempts to parse out the CHLO. 64 void IngestPacket(const ParsedQuicVersion& version, 65 const QuicReceivedPacket& packet); 66 67 // Returns whether the ingested packets have allowed parsing a complete CHLO. HasParsedFullChlo()68 bool HasParsedFullChlo() const { 69 return state_ == State::kParsedFullSinglePacketChlo || 70 state_ == State::kParsedFullMultiPacketChlo; 71 } 72 73 // Returns the TLS alert that caused the unrecoverable error, if any. tls_alert()74 std::optional<uint8_t> tls_alert() const { 75 QUICHE_DCHECK(!tls_alert_.has_value() || 76 state_ == State::kUnrecoverableFailure); 77 return tls_alert_; 78 } 79 80 // Methods from QuicFramerVisitorInterface. OnError(QuicFramer *)81 void OnError(QuicFramer* /*framer*/) override {} 82 bool OnProtocolVersionMismatch(ParsedQuicVersion version) override; OnPacket()83 void OnPacket() override {} OnVersionNegotiationPacket(const QuicVersionNegotiationPacket &)84 void OnVersionNegotiationPacket( 85 const QuicVersionNegotiationPacket& /*packet*/) override {} OnRetryPacket(QuicConnectionId,QuicConnectionId,absl::string_view,absl::string_view,absl::string_view)86 void OnRetryPacket(QuicConnectionId /*original_connection_id*/, 87 QuicConnectionId /*new_connection_id*/, 88 absl::string_view /*retry_token*/, 89 absl::string_view /*retry_integrity_tag*/, 90 absl::string_view /*retry_without_tag*/) override {} 91 bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override; OnUnauthenticatedHeader(const QuicPacketHeader &)92 bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override { 93 return true; 94 } OnDecryptedPacket(size_t,EncryptionLevel)95 void OnDecryptedPacket(size_t /*packet_length*/, 96 EncryptionLevel /*level*/) override {} OnPacketHeader(const QuicPacketHeader &)97 bool OnPacketHeader(const QuicPacketHeader& /*header*/) override { 98 return true; 99 } OnCoalescedPacket(const QuicEncryptedPacket &)100 void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {} OnUndecryptablePacket(const QuicEncryptedPacket &,EncryptionLevel,bool)101 void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/, 102 EncryptionLevel /*decryption_level*/, 103 bool /*has_decryption_key*/) override {} OnStreamFrame(const QuicStreamFrame &)104 bool OnStreamFrame(const QuicStreamFrame& /*frame*/) override { return true; } 105 bool OnCryptoFrame(const QuicCryptoFrame& frame) override; OnAckFrameStart(QuicPacketNumber,QuicTime::Delta)106 bool OnAckFrameStart(QuicPacketNumber /*largest_acked*/, 107 QuicTime::Delta /*ack_delay_time*/) override { 108 return true; 109 } OnAckRange(QuicPacketNumber,QuicPacketNumber)110 bool OnAckRange(QuicPacketNumber /*start*/, 111 QuicPacketNumber /*end*/) override { 112 return true; 113 } OnAckTimestamp(QuicPacketNumber,QuicTime)114 bool OnAckTimestamp(QuicPacketNumber /*packet_number*/, 115 QuicTime /*timestamp*/) override { 116 return true; 117 } OnAckFrameEnd(QuicPacketNumber,const std::optional<QuicEcnCounts> &)118 bool OnAckFrameEnd( 119 QuicPacketNumber /*start*/, 120 const std::optional<QuicEcnCounts>& /*ecn_counts*/) override { 121 return true; 122 } OnStopWaitingFrame(const QuicStopWaitingFrame &)123 bool OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) override { 124 return true; 125 } OnPingFrame(const QuicPingFrame &)126 bool OnPingFrame(const QuicPingFrame& /*frame*/) override { return true; } OnRstStreamFrame(const QuicRstStreamFrame &)127 bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) override { 128 return true; 129 } OnConnectionCloseFrame(const QuicConnectionCloseFrame &)130 bool OnConnectionCloseFrame( 131 const QuicConnectionCloseFrame& /*frame*/) override { 132 return true; 133 } OnNewConnectionIdFrame(const QuicNewConnectionIdFrame &)134 bool OnNewConnectionIdFrame( 135 const QuicNewConnectionIdFrame& /*frame*/) override { 136 return true; 137 } OnRetireConnectionIdFrame(const QuicRetireConnectionIdFrame &)138 bool OnRetireConnectionIdFrame( 139 const QuicRetireConnectionIdFrame& /*frame*/) override { 140 return true; 141 } OnNewTokenFrame(const QuicNewTokenFrame &)142 bool OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) override { 143 return true; 144 } OnStopSendingFrame(const QuicStopSendingFrame &)145 bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override { 146 return true; 147 } OnPathChallengeFrame(const QuicPathChallengeFrame &)148 bool OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) override { 149 return true; 150 } OnPathResponseFrame(const QuicPathResponseFrame &)151 bool OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) override { 152 return true; 153 } OnGoAwayFrame(const QuicGoAwayFrame &)154 bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) override { return true; } OnMaxStreamsFrame(const QuicMaxStreamsFrame &)155 bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override { 156 return true; 157 } OnStreamsBlockedFrame(const QuicStreamsBlockedFrame &)158 bool OnStreamsBlockedFrame( 159 const QuicStreamsBlockedFrame& /*frame*/) override { 160 return true; 161 } OnWindowUpdateFrame(const QuicWindowUpdateFrame &)162 bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override { 163 return true; 164 } OnBlockedFrame(const QuicBlockedFrame &)165 bool OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override { 166 return true; 167 } OnPaddingFrame(const QuicPaddingFrame &)168 bool OnPaddingFrame(const QuicPaddingFrame& /*frame*/) override { 169 return true; 170 } OnMessageFrame(const QuicMessageFrame &)171 bool OnMessageFrame(const QuicMessageFrame& /*frame*/) override { 172 return true; 173 } OnHandshakeDoneFrame(const QuicHandshakeDoneFrame &)174 bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override { 175 return true; 176 } OnAckFrequencyFrame(const QuicAckFrequencyFrame &)177 bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& /*frame*/) override { 178 return true; 179 } OnPacketComplete()180 void OnPacketComplete() override {} IsValidStatelessResetToken(const StatelessResetToken &)181 bool IsValidStatelessResetToken( 182 const StatelessResetToken& /*token*/) const override { 183 return true; 184 } OnAuthenticatedIetfStatelessResetPacket(const QuicIetfStatelessResetPacket &)185 void OnAuthenticatedIetfStatelessResetPacket( 186 const QuicIetfStatelessResetPacket& /*packet*/) override {} OnKeyUpdate(KeyUpdateReason)187 void OnKeyUpdate(KeyUpdateReason /*reason*/) override {} OnDecryptedFirstPacketInKeyPhase()188 void OnDecryptedFirstPacketInKeyPhase() override {} AdvanceKeysAndCreateCurrentOneRttDecrypter()189 std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter() 190 override { 191 return nullptr; 192 } CreateCurrentOneRttEncrypter()193 std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override { 194 return nullptr; 195 } 196 197 // Methods from QuicStreamSequencer::StreamInterface. 198 void OnDataAvailable() override; OnFinRead()199 void OnFinRead() override {} AddBytesConsumed(QuicByteCount)200 void AddBytesConsumed(QuicByteCount /*bytes*/) override {} ResetWithError(QuicResetStreamError)201 void ResetWithError(QuicResetStreamError /*error*/) override {} 202 void OnUnrecoverableError(QuicErrorCode error, 203 const std::string& details) override; 204 void OnUnrecoverableError(QuicErrorCode error, 205 QuicIetfTransportErrorCodes ietf_error, 206 const std::string& details) override; id()207 QuicStreamId id() const override { return 0; } version()208 ParsedQuicVersion version() const override { return framer_->version(); } 209 210 private: 211 // Parses the length of the CHLO message by looking at the first four bytes. 212 // Returns whether we have received enough data to parse the full CHLO now. 213 bool MaybeAttemptToParseChloLength(); 214 // Parses the full CHLO message if enough data has been received. 215 void AttemptToParseFullChlo(); 216 // Moves to the failed state and records the error details. 217 void HandleUnrecoverableError(const std::string& error_details); 218 // Lazily sets up shared SSL handles if needed. 219 static std::pair<SSL_CTX*, int> GetSharedSslHandles(); 220 // Lazily sets up the per-instance SSL handle if needed. 221 void SetupSslHandle(); 222 // Extract the TlsChloExtractor instance from |ssl|. 223 static TlsChloExtractor* GetInstanceFromSSL(SSL* ssl); 224 225 // BoringSSL static TLS callbacks. 226 static enum ssl_select_cert_result_t SelectCertCallback( 227 const SSL_CLIENT_HELLO* client_hello); 228 static int SetReadSecretCallback(SSL* ssl, enum ssl_encryption_level_t level, 229 const SSL_CIPHER* cipher, 230 const uint8_t* secret, size_t secret_length); 231 static int SetWriteSecretCallback(SSL* ssl, enum ssl_encryption_level_t level, 232 const SSL_CIPHER* cipher, 233 const uint8_t* secret, 234 size_t secret_length); 235 static int WriteMessageCallback(SSL* ssl, enum ssl_encryption_level_t level, 236 const uint8_t* data, size_t len); 237 static int FlushFlightCallback(SSL* ssl); 238 static int SendAlertCallback(SSL* ssl, enum ssl_encryption_level_t level, 239 uint8_t desc); 240 241 // Called by SelectCertCallback. 242 void HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello); 243 // Called by callbacks that should never be called. 244 void HandleUnexpectedCallback(const std::string& callback_name); 245 // Called by SendAlertCallback. 246 void SendAlert(uint8_t tls_alert_value); 247 248 // Used to parse received packets to extract single frames. 249 std::unique_ptr<QuicFramer> framer_; 250 // Used to reassemble the crypto stream from received CRYPTO frames. 251 QuicStreamSequencer crypto_stream_sequencer_; 252 // BoringSSL handle required to parse the CHLO. 253 bssl::UniquePtr<SSL> ssl_; 254 // State of this TlsChloExtractor. 255 State state_; 256 // Detail string that can be logged in the presence of unrecoverable errors. 257 std::string error_details_; 258 // Whether a CRYPTO frame was parsed in this packet. 259 bool parsed_crypto_frame_in_this_packet_; 260 // Array of NamedGroups parsed from the CHLO's supported_groups extension. 261 std::vector<uint16_t> supported_groups_; 262 // Array of ALPNs parsed from the CHLO. 263 std::vector<std::string> alpns_; 264 // SNI parsed from the CHLO. 265 std::string server_name_; 266 // Whether resumption is attempted from the CHLO, indicated by the 267 // 'pre_shared_key' TLS extension. 268 bool resumption_attempted_ = false; 269 // Whether early data is attempted from the CHLO, indicated by the 270 // 'early_data' TLS extension. 271 bool early_data_attempted_ = false; 272 // If set, contains the TLS alert that caused an unrecoverable error, which is 273 // an AlertDescription value defined in go/rfc/8446#appendix-B.2. 274 std::optional<uint8_t> tls_alert_; 275 // Exact TLS message bytes. 276 std::vector<uint8_t> client_hello_bytes_; 277 }; 278 279 // Convenience method to facilitate logging TlsChloExtractor::State. 280 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os, 281 const TlsChloExtractor::State& state); 282 283 } // namespace quic 284 285 #endif // QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_ 286