xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/tls_chlo_extractor.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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