blob: 6a941e71d9bfdc378c9a33e529cda8ddb5185360 [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#include "net/third_party/quiche/src/quic/core/quic_crypto_stream.h"
6
7#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
8#include "net/third_party/quiche/src/quic/core/crypto/crypto_utils.h"
9#include "net/third_party/quiche/src/quic/core/quic_connection.h"
10#include "net/third_party/quiche/src/quic/core/quic_session.h"
11#include "net/third_party/quiche/src/quic/core/quic_utils.h"
12#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
17
18namespace quic {
19
20#define ENDPOINT \
21 (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
22 : "Client:" \
23 " ")
24
25QuicCryptoStream::QuicCryptoStream(QuicSession* session)
26 : QuicStream(QuicUtils::GetCryptoStreamId(
27 session->connection()->transport_version()),
28 session,
29 /*is_static=*/true,
30 BIDIRECTIONAL),
31 substreams_{{this, ENCRYPTION_NONE},
32 {this, ENCRYPTION_ZERO_RTT},
33 {this, ENCRYPTION_FORWARD_SECURE}} {
34 // The crypto stream is exempt from connection level flow control.
35 DisableConnectionFlowControlForThisStream();
36}
37
38QuicCryptoStream::~QuicCryptoStream() {}
39
40// static
41QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead(
42 QuicTransportVersion version,
43 QuicConnectionId connection_id) {
44 DCHECK(QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
45 return QuicPacketCreator::StreamFramePacketOverhead(
46 version, static_cast<QuicConnectionIdLength>(connection_id.length()),
47 PACKET_0BYTE_CONNECTION_ID,
48 /*include_version=*/true,
49 /*include_diversification_nonce=*/true,
50 version > QUIC_VERSION_43 ? PACKET_4BYTE_PACKET_NUMBER
51 : PACKET_1BYTE_PACKET_NUMBER,
52 VARIABLE_LENGTH_INTEGER_LENGTH_1, VARIABLE_LENGTH_INTEGER_LENGTH_2,
53 /*offset=*/0);
54}
55
56void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
57 QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
58 << "Versions less than 47 shouldn't receive CRYPTO frames";
59 EncryptionLevel level = session()->connection()->last_decrypted_level();
60 substreams_[level].sequencer.OnCryptoFrame(frame);
61}
62
63void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
64 if (session()->connection()->transport_version() >= QUIC_VERSION_47) {
65 QUIC_PEER_BUG
66 << "Crypto data received in stream frame instead of crypto frame";
67 CloseConnectionWithDetails(QUIC_INVALID_STREAM_DATA,
68 "Unexpected stream frame");
69 }
70 QuicStream::OnStreamFrame(frame);
71}
72
73void QuicCryptoStream::OnDataAvailable() {
74 EncryptionLevel level = session()->connection()->last_decrypted_level();
75 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
76 // Versions less than 47 only support QUIC crypto, which ignores the
77 // EncryptionLevel passed into CryptoMessageParser::ProcessInput (and
78 // OnDataAvailableInSequencer).
79 OnDataAvailableInSequencer(sequencer(), level);
80 return;
81 }
82 OnDataAvailableInSequencer(&substreams_[level].sequencer, level);
83}
84
85void QuicCryptoStream::OnDataAvailableInSequencer(
86 QuicStreamSequencer* sequencer,
87 EncryptionLevel level) {
88 struct iovec iov;
89 while (sequencer->GetReadableRegion(&iov)) {
90 QuicStringPiece data(static_cast<char*>(iov.iov_base), iov.iov_len);
91 if (!crypto_message_parser()->ProcessInput(data, level)) {
92 CloseConnectionWithDetails(crypto_message_parser()->error(),
93 crypto_message_parser()->error_detail());
94 return;
95 }
96 sequencer->MarkConsumed(iov.iov_len);
97 if (handshake_confirmed() &&
98 crypto_message_parser()->InputBytesRemaining() == 0) {
99 // If the handshake is complete and the current message has been fully
100 // processed then no more handshake messages are likely to arrive soon
101 // so release the memory in the stream sequencer.
102 sequencer->ReleaseBufferIfEmpty();
103 }
104 }
105}
106
107bool QuicCryptoStream::ExportKeyingMaterial(QuicStringPiece label,
108 QuicStringPiece context,
109 size_t result_len,
vasilvvc48c8712019-03-11 13:38:16 -0700110 std::string* result) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500111 if (!handshake_confirmed()) {
112 QUIC_DLOG(ERROR) << "ExportKeyingMaterial was called before forward-secure"
113 << "encryption was established.";
114 return false;
115 }
116 return CryptoUtils::ExportKeyingMaterial(
117 crypto_negotiated_params().subkey_secret, label, context, result_len,
118 result);
119}
120
121void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
122 QuicStringPiece data) {
123 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
124 // The QUIC crypto handshake takes care of setting the appropriate
125 // encryption level before writing data. Since that is the only handshake
126 // supported in versions less than 47, |level| can be ignored here.
127 WriteOrBufferData(data, /* fin */ false, /* ack_listener */ nullptr);
128 return;
129 }
130 if (data.empty()) {
131 QUIC_BUG << "Empty crypto data being written";
132 return;
133 }
134 // Append |data| to the send buffer for this encryption level.
135 struct iovec iov(QuicUtils::MakeIovec(data));
136 QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
137 QuicStreamOffset offset = send_buffer->stream_offset();
138 send_buffer->SaveStreamData(&iov, /*iov_count=*/1, /*iov_offset=*/0,
139 data.length());
140 if (kMaxStreamLength - offset < data.length()) {
141 QUIC_BUG << "Writing too much crypto handshake data";
142 // TODO(nharper): Switch this to an IETF QUIC error code, possibly
143 // INTERNAL_ERROR?
144 CloseConnectionWithDetails(QUIC_STREAM_LENGTH_OVERFLOW,
145 "Writing too much crypto handshake data");
146 }
147
148 EncryptionLevel current_level = session()->connection()->encryption_level();
149 session()->connection()->SetDefaultEncryptionLevel(level);
150 size_t bytes_consumed =
151 session()->connection()->SendCryptoData(level, data.length(), offset);
152 session()->connection()->SetDefaultEncryptionLevel(current_level);
153
154 send_buffer->OnStreamDataConsumed(bytes_consumed);
155}
156
157void QuicCryptoStream::OnSuccessfulVersionNegotiation(
158 const ParsedQuicVersion& version) {}
159
160bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
161 QuicTime::Delta ack_delay_time) {
162 QuicByteCount newly_acked_length = 0;
163 if (!substreams_[frame.level].send_buffer.OnStreamDataAcked(
164 frame.offset, frame.data_length, &newly_acked_length)) {
165 CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
166 "Trying to ack unsent crypto data.");
167 return false;
168 }
169 return newly_acked_length > 0;
170}
171
172void QuicCryptoStream::NeuterUnencryptedStreamData() {
173 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
174 for (const auto& interval : bytes_consumed_[ENCRYPTION_NONE]) {
175 QuicByteCount newly_acked_length = 0;
176 send_buffer().OnStreamDataAcked(
177 interval.min(), interval.max() - interval.min(), &newly_acked_length);
178 }
179 return;
180 }
181 QuicStreamSendBuffer* send_buffer = &substreams_[ENCRYPTION_NONE].send_buffer;
182 // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer to
183 // replace the following code.
184 QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
185 to_ack.Complement(0, send_buffer->stream_offset());
186 for (const auto& interval : to_ack) {
187 QuicByteCount newly_acked_length = 0;
188 send_buffer->OnStreamDataAcked(
189 interval.min(), interval.max() - interval.min(), &newly_acked_length);
190 }
191}
192
193void QuicCryptoStream::OnStreamDataConsumed(size_t bytes_consumed) {
194 if (session()->connection()->transport_version() >= QUIC_VERSION_47) {
195 QUIC_BUG << "Stream data consumed when CRYPTO frames should be in use";
196 }
197 if (bytes_consumed > 0) {
198 bytes_consumed_[session()->connection()->encryption_level()].Add(
199 stream_bytes_written(), stream_bytes_written() + bytes_consumed);
200 }
201 QuicStream::OnStreamDataConsumed(bytes_consumed);
202}
203
204bool QuicCryptoStream::HasPendingCryptoRetransmission() {
205 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
206 return false;
207 }
208 for (EncryptionLevel level :
209 {ENCRYPTION_NONE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
210 if (substreams_[level].send_buffer.HasPendingRetransmission()) {
211 return true;
212 }
213 }
214 return false;
215}
216
217void QuicCryptoStream::WritePendingCryptoRetransmission() {
218 QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
219 << "Versions less than 47 don't write CRYPTO frames";
220 EncryptionLevel current_encryption_level =
221 session()->connection()->encryption_level();
222 for (EncryptionLevel level :
223 {ENCRYPTION_NONE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
224 QuicStreamSendBuffer* send_buffer = &substreams_[level].send_buffer;
225 session()->connection()->SetDefaultEncryptionLevel(level);
226 while (send_buffer->HasPendingRetransmission()) {
227 auto pending = send_buffer->NextPendingRetransmission();
228 size_t bytes_consumed = session()->connection()->SendCryptoData(
229 level, pending.length, pending.offset);
230 send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
231 }
232 }
233 session()->connection()->SetDefaultEncryptionLevel(current_encryption_level);
234}
235
236void QuicCryptoStream::WritePendingRetransmission() {
237 while (HasPendingRetransmission()) {
238 StreamPendingRetransmission pending =
239 send_buffer().NextPendingRetransmission();
240 QuicIntervalSet<QuicStreamOffset> retransmission(
241 pending.offset, pending.offset + pending.length);
242 EncryptionLevel retransmission_encryption_level = ENCRYPTION_NONE;
243 // Determine the encryption level to write the retransmission
244 // at. The retransmission should be written at the same encryption level
245 // as the original transmission.
246 for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
247 if (retransmission.Intersects(bytes_consumed_[i])) {
248 retransmission_encryption_level = static_cast<EncryptionLevel>(i);
249 retransmission.Intersection(bytes_consumed_[i]);
250 break;
251 }
252 }
253 pending.offset = retransmission.begin()->min();
254 pending.length =
255 retransmission.begin()->max() - retransmission.begin()->min();
256 EncryptionLevel current_encryption_level =
257 session()->connection()->encryption_level();
258 // Set appropriate encryption level.
259 session()->connection()->SetDefaultEncryptionLevel(
260 retransmission_encryption_level);
261 QuicConsumedData consumed = session()->WritevData(
262 this, id(), pending.length, pending.offset, NO_FIN);
263 QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
264 << " tries to retransmit stream data [" << pending.offset
265 << ", " << pending.offset + pending.length
266 << ") with encryption level: "
267 << retransmission_encryption_level
268 << ", consumed: " << consumed;
269 OnStreamFrameRetransmitted(pending.offset, consumed.bytes_consumed,
270 consumed.fin_consumed);
271 // Restore encryption level.
272 session()->connection()->SetDefaultEncryptionLevel(
273 current_encryption_level);
274 if (consumed.bytes_consumed < pending.length) {
275 // The connection is write blocked.
276 break;
277 }
278 }
279}
280
281bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset,
282 QuicByteCount data_length,
283 bool /*fin*/) {
284 QuicIntervalSet<QuicStreamOffset> retransmission(offset,
285 offset + data_length);
286 // Determine the encryption level to send data. This only needs to be once as
287 // [offset, offset + data_length) is guaranteed to be in the same packet.
288 EncryptionLevel send_encryption_level = ENCRYPTION_NONE;
289 for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
290 if (retransmission.Intersects(bytes_consumed_[i])) {
291 send_encryption_level = static_cast<EncryptionLevel>(i);
292 break;
293 }
294 }
295 retransmission.Difference(bytes_acked());
296 EncryptionLevel current_encryption_level =
297 session()->connection()->encryption_level();
298 for (const auto& interval : retransmission) {
299 QuicStreamOffset retransmission_offset = interval.min();
300 QuicByteCount retransmission_length = interval.max() - interval.min();
301 // Set appropriate encryption level.
302 session()->connection()->SetDefaultEncryptionLevel(send_encryption_level);
303 QuicConsumedData consumed = session()->WritevData(
304 this, id(), retransmission_length, retransmission_offset, NO_FIN);
305 QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
306 << " is forced to retransmit stream data ["
307 << retransmission_offset << ", "
308 << retransmission_offset + retransmission_length
309 << "), with encryption level: " << send_encryption_level
310 << ", consumed: " << consumed;
311 OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
312 consumed.fin_consumed);
313 // Restore encryption level.
314 session()->connection()->SetDefaultEncryptionLevel(
315 current_encryption_level);
316 if (consumed.bytes_consumed < retransmission_length) {
317 // The connection is write blocked.
318 return false;
319 }
320 }
321
322 return true;
323}
324
325uint64_t QuicCryptoStream::crypto_bytes_read() const {
326 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
327 return stream_bytes_read();
328 }
329 return substreams_[ENCRYPTION_NONE].sequencer.NumBytesConsumed() +
330 substreams_[ENCRYPTION_ZERO_RTT].sequencer.NumBytesConsumed() +
331 substreams_[ENCRYPTION_FORWARD_SECURE].sequencer.NumBytesConsumed();
332}
333
334uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
335 return substreams_[level].sequencer.NumBytesConsumed();
336}
337
338bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
339 QuicStreamOffset offset,
340 QuicByteCount data_length,
341 QuicDataWriter* writer) {
342 QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
343 << "Versions less than 47 don't write CRYPTO frames (2)";
344 return substreams_[level].send_buffer.WriteStreamData(offset, data_length,
345 writer);
346}
347
348void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
349 QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
350 << "Versions less than 47 don't lose CRYPTO frames";
351 substreams_[crypto_frame->level].send_buffer.OnStreamDataLost(
352 crypto_frame->offset, crypto_frame->data_length);
353}
354
355void QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame) {
356 QUIC_BUG_IF(session()->connection()->transport_version() < QUIC_VERSION_47)
357 << "Versions less than 47 don't retransmit CRYPTO frames";
358 QuicIntervalSet<QuicStreamOffset> retransmission(
359 crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
360 QuicStreamSendBuffer* send_buffer =
361 &substreams_[crypto_frame->level].send_buffer;
362 retransmission.Difference(send_buffer->bytes_acked());
363 if (retransmission.Empty()) {
364 return;
365 }
366 EncryptionLevel current_encryption_level =
367 session()->connection()->encryption_level();
368 for (const auto& interval : retransmission) {
369 size_t retransmission_offset = interval.min();
370 size_t retransmission_length = interval.max() - interval.min();
371 session()->connection()->SetDefaultEncryptionLevel(crypto_frame->level);
372 size_t bytes_consumed = session()->connection()->SendCryptoData(
373 crypto_frame->level, retransmission_length, retransmission_offset);
374 send_buffer->OnStreamDataRetransmitted(retransmission_offset,
375 bytes_consumed);
376 }
377 session()->connection()->SetDefaultEncryptionLevel(current_encryption_level);
378}
379
380bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level,
381 size_t offset,
382 size_t length) const {
383 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
384 // This only happens if a client was originally configured for a version
385 // greater than 45, but received a version negotiation packet and is
386 // attempting to retransmit for a version less than 47. Outside of tests,
387 // this is a misconfiguration of the client, and this connection will be
388 // doomed. Return false here to avoid trying to retransmit CRYPTO frames on
389 // the wrong transport version.
390 return false;
391 }
392 return substreams_[level].send_buffer.IsStreamDataOutstanding(offset, length);
393}
394
395bool QuicCryptoStream::IsWaitingForAcks() const {
396 if (session()->connection()->transport_version() < QUIC_VERSION_47) {
397 return QuicStream::IsWaitingForAcks();
398 }
399 for (EncryptionLevel level :
400 {ENCRYPTION_NONE, ENCRYPTION_ZERO_RTT, ENCRYPTION_FORWARD_SECURE}) {
401 if (substreams_[level].send_buffer.stream_bytes_outstanding()) {
402 return true;
403 }
404 }
405 return false;
406}
407
408QuicCryptoStream::CryptoSubstream::CryptoSubstream(
409 QuicCryptoStream* crypto_stream,
410 EncryptionLevel)
411 : sequencer(crypto_stream),
412 send_buffer(crypto_stream->session()
413 ->connection()
414 ->helper()
415 ->GetStreamSendBufferAllocator()) {}
416
417#undef ENDPOINT // undef for jumbo builds
418} // namespace quic