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