• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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