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