• 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 <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