blob: 1762566d70a235a892f21d1963d631b19046f962 [file] [log] [blame]
dschinazie4ac5072020-04-22 18:56:23 -07001// 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#include "third_party/boringssl/src/include/openssl/ssl.h"
12#include "net/third_party/quiche/src/quic/core/quic_framer.h"
13#include "net/third_party/quiche/src/quic/core/quic_packets.h"
14#include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
16
17namespace quic {
18
19// Utility class that allows extracting information from a QUIC-TLS Client
20// Hello. This class creates a QuicFramer to parse the packet, and implements
21// QuicFramerVisitorInterface to access the frames parsed by the QuicFramer. It
22// then uses a QuicStreamSequencer to reassemble the contents of the crypto
23// stream, and implements QuicStreamSequencer::StreamInterface to access the
24// reassembled data.
25class QUIC_NO_EXPORT TlsChloExtractor
26 : public QuicFramerVisitorInterface,
27 public QuicStreamSequencer::StreamInterface {
28 public:
29 TlsChloExtractor();
30 TlsChloExtractor(const TlsChloExtractor&) = delete;
dschinazi16fbfdf2020-04-23 18:33:55 -070031 TlsChloExtractor(TlsChloExtractor&&);
dschinazie4ac5072020-04-22 18:56:23 -070032 TlsChloExtractor& operator=(const TlsChloExtractor&) = delete;
dschinazi16fbfdf2020-04-23 18:33:55 -070033 TlsChloExtractor& operator=(TlsChloExtractor&&);
dschinazie4ac5072020-04-22 18:56:23 -070034
35 enum class State : uint8_t {
36 kInitial = 0,
37 kParsedFullSinglePacketChlo = 1,
38 kParsedFullMultiPacketChlo = 2,
39 kParsedPartialChloFragment = 3,
40 kUnrecoverableFailure = 4,
41 };
42
43 State state() const { return state_; }
44 std::vector<std::string> alpns() const { return alpns_; }
45 std::string server_name() const { return server_name_; }
46
47 // Converts |state| to a human-readable string suitable for logging.
48 static std::string StateToString(State state);
49
50 // Ingests |packet| and attempts to parse out the CHLO.
51 void IngestPacket(const ParsedQuicVersion& version,
52 const QuicReceivedPacket& packet);
53
54 // Returns whether the ingested packets have allowed parsing a complete CHLO.
55 bool HasParsedFullChlo() const {
56 return state_ == State::kParsedFullSinglePacketChlo ||
57 state_ == State::kParsedFullMultiPacketChlo;
58 }
59
60 // Methods from QuicFramerVisitorInterface.
61 void OnError(QuicFramer* /*framer*/) override {}
62 bool OnProtocolVersionMismatch(ParsedQuicVersion version) override;
63 void OnPacket() override {}
64 void OnPublicResetPacket(const QuicPublicResetPacket& /*packet*/) override {}
65 void OnVersionNegotiationPacket(
66 const QuicVersionNegotiationPacket& /*packet*/) override {}
67 void OnRetryPacket(QuicConnectionId /*original_connection_id*/,
68 QuicConnectionId /*new_connection_id*/,
69 quiche::QuicheStringPiece /*retry_token*/,
70 quiche::QuicheStringPiece /*retry_integrity_tag*/,
71 quiche::QuicheStringPiece /*retry_without_tag*/) override {
72 }
73 bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
74 bool OnUnauthenticatedHeader(const QuicPacketHeader& /*header*/) override {
75 return true;
76 }
77 void OnDecryptedPacket(EncryptionLevel /*level*/) override {}
78 bool OnPacketHeader(const QuicPacketHeader& /*header*/) override {
79 return true;
80 }
81 void OnCoalescedPacket(const QuicEncryptedPacket& /*packet*/) override {}
82 void OnUndecryptablePacket(const QuicEncryptedPacket& /*packet*/,
83 EncryptionLevel /*decryption_level*/,
84 bool /*has_decryption_key*/) override {}
85 bool OnStreamFrame(const QuicStreamFrame& /*frame*/) override { return true; }
86 bool OnCryptoFrame(const QuicCryptoFrame& frame) override;
87 bool OnAckFrameStart(QuicPacketNumber /*largest_acked*/,
88 QuicTime::Delta /*ack_delay_time*/) override {
89 return true;
90 }
91 bool OnAckRange(QuicPacketNumber /*start*/,
92 QuicPacketNumber /*end*/) override {
93 return true;
94 }
95 bool OnAckTimestamp(QuicPacketNumber /*packet_number*/,
96 QuicTime /*timestamp*/) override {
97 return true;
98 }
99 bool OnAckFrameEnd(QuicPacketNumber /*start*/) override { return true; }
100 bool OnStopWaitingFrame(const QuicStopWaitingFrame& /*frame*/) override {
101 return true;
102 }
103 bool OnPingFrame(const QuicPingFrame& /*frame*/) override { return true; }
104 bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) override {
105 return true;
106 }
107 bool OnConnectionCloseFrame(
108 const QuicConnectionCloseFrame& /*frame*/) override {
109 return true;
110 }
111 bool OnNewConnectionIdFrame(
112 const QuicNewConnectionIdFrame& /*frame*/) override {
113 return true;
114 }
115 bool OnRetireConnectionIdFrame(
116 const QuicRetireConnectionIdFrame& /*frame*/) override {
117 return true;
118 }
119 bool OnNewTokenFrame(const QuicNewTokenFrame& /*frame*/) override {
120 return true;
121 }
122 bool OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {
123 return true;
124 }
125 bool OnPathChallengeFrame(const QuicPathChallengeFrame& /*frame*/) override {
126 return true;
127 }
128 bool OnPathResponseFrame(const QuicPathResponseFrame& /*frame*/) override {
129 return true;
130 }
131 bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) override { return true; }
132 bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& /*frame*/) override {
133 return true;
134 }
135 bool OnStreamsBlockedFrame(
136 const QuicStreamsBlockedFrame& /*frame*/) override {
137 return true;
138 }
139 bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& /*frame*/) override {
140 return true;
141 }
142 bool OnBlockedFrame(const QuicBlockedFrame& /*frame*/) override {
143 return true;
144 }
145 bool OnPaddingFrame(const QuicPaddingFrame& /*frame*/) override {
146 return true;
147 }
148 bool OnMessageFrame(const QuicMessageFrame& /*frame*/) override {
149 return true;
150 }
151 bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& /*frame*/) override {
152 return true;
153 }
154 void OnPacketComplete() override {}
155 bool IsValidStatelessResetToken(QuicUint128 /*token*/) const override {
156 return true;
157 }
158 void OnAuthenticatedIetfStatelessResetPacket(
159 const QuicIetfStatelessResetPacket& /*packet*/) override {}
160
161 // Methods from QuicStreamSequencer::StreamInterface.
162 void OnDataAvailable() override;
163 void OnFinRead() override {}
164 void AddBytesConsumed(QuicByteCount /*bytes*/) override {}
165 void Reset(QuicRstStreamErrorCode /*error*/) override {}
166 void OnUnrecoverableError(QuicErrorCode error,
167 const std::string& details) override;
168 QuicStreamId id() const override { return 0; }
169
170 private:
171 // Parses the length of the CHLO message by looking at the first four bytes.
172 // Returns whether we have received enough data to parse the full CHLO now.
173 bool MaybeAttemptToParseChloLength();
174 // Parses the full CHLO message if enough data has been received.
175 void AttemptToParseFullChlo();
176 // Moves to the failed state and records the error details.
177 void HandleUnrecoverableError(const std::string& error_details);
178 // Lazily sets up shared SSL handles if needed.
179 static std::pair<SSL_CTX*, int> GetSharedSslHandles();
180 // Lazily sets up the per-instance SSL handle if needed.
181 void SetupSslHandle();
182 // Extract the TlsChloExtractor instance from |ssl|.
183 static TlsChloExtractor* GetInstanceFromSSL(SSL* ssl);
184
185 // BoringSSL static TLS callbacks.
186 static enum ssl_select_cert_result_t SelectCertCallback(
187 const SSL_CLIENT_HELLO* client_hello);
188 static int SetReadSecretCallback(SSL* ssl,
189 enum ssl_encryption_level_t level,
190 const SSL_CIPHER* cipher,
191 const uint8_t* secret,
192 size_t secret_length);
193 static int SetWriteSecretCallback(SSL* ssl,
194 enum ssl_encryption_level_t level,
195 const SSL_CIPHER* cipher,
196 const uint8_t* secret,
197 size_t secret_length);
198 static int WriteMessageCallback(SSL* ssl,
199 enum ssl_encryption_level_t level,
200 const uint8_t* data,
201 size_t len);
202 static int FlushFlightCallback(SSL* ssl);
203 static int SendAlertCallback(SSL* ssl,
204 enum ssl_encryption_level_t level,
205 uint8_t desc);
206
207 // Called by SelectCertCallback.
208 void HandleParsedChlo(const SSL_CLIENT_HELLO* client_hello);
209 // Called by callbacks that should never be called.
210 void HandleUnexpectedCallback(const std::string& callback_name);
211 // Called by SendAlertCallback.
212 void SendAlert(uint8_t tls_alert_value);
213
214 // Used to parse received packets to extract single frames.
215 std::unique_ptr<QuicFramer> framer_;
216 // Used to reassemble the crypto stream from received CRYPTO frames.
217 QuicStreamSequencer crypto_stream_sequencer_;
218 // BoringSSL handle required to parse the CHLO.
219 bssl::UniquePtr<SSL> ssl_;
220 // State of this TlsChloExtractor.
221 State state_;
222 // Detail string that can be logged in the presence of unrecoverable errors.
223 std::string error_details_;
224 // Whether a CRYPTO frame was parsed in this packet.
225 bool parsed_crypto_frame_in_this_packet_;
226 // Array of ALPNs parsed from the CHLO.
227 std::vector<std::string> alpns_;
228 // SNI parsed from the CHLO.
229 std::string server_name_;
230};
231
dschinazi16fbfdf2020-04-23 18:33:55 -0700232// Convenience method to facilitate logging TlsChloExtractor::State.
233QUIC_NO_EXPORT std::ostream& operator<<(std::ostream& os,
234 const TlsChloExtractor::State& state);
235
dschinazie4ac5072020-04-22 18:56:23 -0700236} // namespace quic
237
238#endif // QUICHE_QUIC_CORE_TLS_CHLO_EXTRACTOR_H_