blob: ea15ded0a3387ea24df316804b73bb00f79b030e [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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_QUIC_CRYPTO_STREAM_H_
6#define QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
7
bnc5e469412019-12-05 14:16:25 -08008#include <array>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include <cstddef>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011
vasilvvc872ee42020-10-07 19:50:22 -070012#include "absl/strings/string_view.h"
nharper6a6bd312020-09-17 13:20:53 -070013#include "third_party/boringssl/src/include/openssl/ssl.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/core/crypto/crypto_framer.h"
15#include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
16#include "net/third_party/quiche/src/quic/core/quic_config.h"
17#include "net/third_party/quiche/src/quic/core/quic_packets.h"
18#include "net/third_party/quiche/src/quic/core/quic_stream.h"
renjietang41a1b412020-02-27 15:05:14 -080019#include "net/third_party/quiche/src/quic/core/quic_types.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050020#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050021
22namespace quic {
23
24class QuicSession;
25
26// Crypto handshake messages in QUIC take place over a reserved stream with the
27// id 1. Each endpoint (client and server) will allocate an instance of a
28// subclass of QuicCryptoStream to send and receive handshake messages. (In the
29// normal 1-RTT handshake, the client will send a client hello, CHLO, message.
30// The server will receive this message and respond with a server hello message,
31// SHLO. At this point both sides will have established a crypto context they
32// can use to send encrypted messages.
33//
34// For more details:
35// https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
36class QUIC_EXPORT_PRIVATE QuicCryptoStream : public QuicStream {
37 public:
38 explicit QuicCryptoStream(QuicSession* session);
39 QuicCryptoStream(const QuicCryptoStream&) = delete;
40 QuicCryptoStream& operator=(const QuicCryptoStream&) = delete;
41
42 ~QuicCryptoStream() override;
43
44 // Returns the per-packet framing overhead associated with sending a
45 // handshake message for |version|.
46 static QuicByteCount CryptoMessageFramingOverhead(
47 QuicTransportVersion version,
48 QuicConnectionId connection_id);
49
50 // QuicStream implementation
51 void OnStreamFrame(const QuicStreamFrame& frame) override;
52 void OnDataAvailable() override;
53
54 // Called when a CRYPTO frame is received.
55 void OnCryptoFrame(const QuicCryptoFrame& frame);
56
57 // Called when a CRYPTO frame is ACKed.
58 bool OnCryptoFrameAcked(const QuicCryptoFrame& frame,
59 QuicTime::Delta ack_delay_time);
60
renjietang546c7142020-03-05 14:12:10 -080061 void OnStreamReset(const QuicRstStreamFrame& frame) override;
62
QUICHE teama6ef0a62019-03-07 20:34:33 -050063 // Performs key extraction to derive a new secret of |result_len| bytes
64 // dependent on |label|, |context|, and the stream's negotiated subkey secret.
65 // Returns false if the handshake has not been confirmed or the parameters are
66 // invalid (e.g. |label| contains null bytes); returns true on success.
vasilvvc872ee42020-10-07 19:50:22 -070067 bool ExportKeyingMaterial(absl::string_view label,
68 absl::string_view context,
QUICHE teama6ef0a62019-03-07 20:34:33 -050069 size_t result_len,
vasilvvc48c8712019-03-11 13:38:16 -070070 std::string* result) const;
QUICHE teama6ef0a62019-03-07 20:34:33 -050071
72 // Writes |data| to the QuicStream at level |level|.
vasilvvc872ee42020-10-07 19:50:22 -070073 virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data);
QUICHE teama6ef0a62019-03-07 20:34:33 -050074
nharper6a6bd312020-09-17 13:20:53 -070075 // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
76 // rejected. Note that the value returned by this function may vary during the
77 // handshake. Once |one_rtt_keys_available| returns true, the value returned
78 // by this function will not change for the rest of the lifetime of the
79 // QuicCryptoStream.
80 virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
81
QUICHE teama6ef0a62019-03-07 20:34:33 -050082 // Returns true once an encrypter has been set for the connection.
83 virtual bool encryption_established() const = 0;
84
85 // Returns true once the crypto handshake has completed.
fayang685367a2020-01-14 10:40:15 -080086 virtual bool one_rtt_keys_available() const = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050087
88 // Returns the parameters negotiated in the crypto handshake.
89 virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
90 const = 0;
91
92 // Provides the message parser to use when data is received on this stream.
93 virtual CryptoMessageParser* crypto_message_parser() = 0;
94
fayangd58736d2019-11-27 13:35:31 -080095 // Called when a packet of encryption |level| has been successfully decrypted.
96 virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
97
fayang2f2915d2020-01-24 06:47:15 -080098 // Called when a 1RTT packet has been acknowledged.
99 virtual void OnOneRttPacketAcknowledged() = 0;
100
fayang44ae4e92020-04-28 13:09:42 -0700101 // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
102 virtual void OnHandshakePacketSent() = 0;
103
fayang01062942020-01-22 07:23:23 -0800104 // Called when a handshake done frame has been received.
105 virtual void OnHandshakeDoneReceived() = 0;
106
fayang9a863cf2020-01-16 14:12:11 -0800107 // Returns current handshake state.
108 virtual HandshakeState GetHandshakeState() const = 0;
109
nharperac52a862020-06-08 12:41:06 -0700110 // Called to provide the server-side application state that must be checked
111 // when performing a 0-RTT TLS resumption.
112 //
113 // On a client, this may be called at any time; 0-RTT tickets will not be
114 // cached until this function is called. When a 0-RTT resumption is attempted,
115 // QuicSession::SetApplicationState will be called with the state provided by
116 // a call to this function on a previous connection.
117 //
118 // On a server, this function must be called before commencing the handshake,
119 // otherwise 0-RTT tickets will not be issued. On subsequent connections,
120 // 0-RTT will be rejected if the data passed into this function does not match
121 // the data passed in on the connection where the 0-RTT ticket was issued.
122 virtual void SetServerApplicationStateForResumption(
123 std::unique_ptr<ApplicationState> state) = 0;
124
nharper486a8a92019-08-28 16:25:10 -0700125 // Returns the maximum number of bytes that can be buffered at a particular
126 // encryption level |level|.
127 virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
128
mattm072a7e32020-10-09 16:16:56 -0700129 // Returns whether the implementation supports key update.
130 virtual bool KeyUpdateSupportedLocally() const = 0;
131
132 // Called to generate a decrypter for the next key phase. Each call should
133 // generate the key for phase n+1.
134 virtual std::unique_ptr<QuicDecrypter>
135 AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
136
137 // Called to generate an encrypter for the same key phase of the last
138 // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
139 virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
140
QUICHE teama6ef0a62019-03-07 20:34:33 -0500141 // Called to cancel retransmission of unencrypted crypto stream data.
142 void NeuterUnencryptedStreamData();
143
fayangbe7b0752020-04-07 11:27:21 -0700144 // Called to cancel retransmission of data of encryption |level|.
145 void NeuterStreamDataOfEncryptionLevel(EncryptionLevel level);
146
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 // Override to record the encryption level of consumed data.
dschinazif1e7b422020-04-30 12:21:28 -0700148 void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500149
150 // Returns whether there are any bytes pending retransmission in CRYPTO
151 // frames.
nharper46833c32019-05-15 21:33:05 -0700152 virtual bool HasPendingCryptoRetransmission() const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500153
154 // Writes any pending CRYPTO frame retransmissions.
155 void WritePendingCryptoRetransmission();
156
157 // Override to retransmit lost crypto data with the appropriate encryption
158 // level.
159 void WritePendingRetransmission() override;
160
161 // Override to send unacked crypto data with the appropriate encryption level.
162 bool RetransmitStreamData(QuicStreamOffset offset,
163 QuicByteCount data_length,
renjietang4d992bf2020-03-03 13:01:55 -0800164 bool fin,
165 TransmissionType type) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500166
renjietang41a1b412020-02-27 15:05:14 -0800167 // Sends stream retransmission data at |encryption_level|.
168 QuicConsumedData RetransmitStreamDataAtLevel(
169 QuicStreamOffset retransmission_offset,
170 QuicByteCount retransmission_length,
renjietang4d992bf2020-03-03 13:01:55 -0800171 EncryptionLevel encryption_level,
172 TransmissionType type);
renjietang41a1b412020-02-27 15:05:14 -0800173
QUICHE teama6ef0a62019-03-07 20:34:33 -0500174 // Returns the number of bytes of handshake data that have been received from
175 // the peer in either CRYPTO or STREAM frames.
176 uint64_t crypto_bytes_read() const;
177
178 // Returns the number of bytes of handshake data that have been received from
179 // the peer in CRYPTO frames at a particular encryption level.
180 QuicByteCount BytesReadOnLevel(EncryptionLevel level) const;
181
182 // Writes |data_length| of data of a crypto frame to |writer|. The data
183 // written is from the send buffer for encryption level |level| and starts at
184 // |offset|.
185 bool WriteCryptoFrame(EncryptionLevel level,
186 QuicStreamOffset offset,
187 QuicByteCount data_length,
188 QuicDataWriter* writer);
189
190 // Called when data from a CRYPTO frame is considered lost. The lost data is
191 // identified by the encryption level, offset, and length in |crypto_frame|.
192 void OnCryptoFrameLost(QuicCryptoFrame* crypto_frame);
193
194 // Called to retransmit any outstanding data in the range indicated by the
195 // encryption level, offset, and length in |crypto_frame|.
renjietang4d992bf2020-03-03 13:01:55 -0800196 void RetransmitData(QuicCryptoFrame* crypto_frame, TransmissionType type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197
fayangaee31ef2019-08-20 06:47:51 -0700198 // Called to write buffered crypto frames.
199 void WriteBufferedCryptoFrames();
200
201 // Returns true if there is buffered crypto frames.
202 bool HasBufferedCryptoFrames() const;
203
QUICHE teama6ef0a62019-03-07 20:34:33 -0500204 // Returns true if any portion of the data at encryption level |level|
205 // starting at |offset| for |length| bytes is outstanding.
206 bool IsFrameOutstanding(EncryptionLevel level,
207 size_t offset,
208 size_t length) const;
209
210 // Returns true if the crypto handshake is still waiting for acks of sent
211 // data, and false if all data has been acked.
212 bool IsWaitingForAcks() const;
213
214 private:
215 // Data sent and received in CRYPTO frames is sent at multiple encryption
216 // levels. Some of the state for the single logical crypto stream is split
217 // across encryption levels, and a CryptoSubstream is used to manage that
218 // state for a particular encryption level.
dschinazif25169a2019-10-23 08:12:18 -0700219 struct QUIC_EXPORT_PRIVATE CryptoSubstream {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220 CryptoSubstream(QuicCryptoStream* crypto_stream, EncryptionLevel);
221
222 QuicStreamSequencer sequencer;
223 QuicStreamSendBuffer send_buffer;
224 };
225
226 // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
227 // with the data available in |sequencer| and |level|, and marks the data
228 // passed to ProcessInput as consumed.
229 void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
230 EncryptionLevel level);
231
232 // Consumed data according to encryption levels.
233 // TODO(fayang): This is not needed once switching from QUIC crypto to
234 // TLS 1.3, which never encrypts crypto data.
235 QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
236
237 // Keeps state for data sent/received in CRYPTO frames at each encryption
238 // level.
bnc5e469412019-12-05 14:16:25 -0800239 std::array<CryptoSubstream, NUM_ENCRYPTION_LEVELS> substreams_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240};
241
242} // namespace quic
243
244#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_