xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // 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 
8 #include <array>
9 #include <cstddef>
10 #include <string>
11 
12 #include "absl/strings/string_view.h"
13 #include "openssl/ssl.h"
14 #include "quiche/quic/core/crypto/crypto_framer.h"
15 #include "quiche/quic/core/crypto/crypto_utils.h"
16 #include "quiche/quic/core/proto/cached_network_parameters_proto.h"
17 #include "quiche/quic/core/quic_config.h"
18 #include "quiche/quic/core/quic_packets.h"
19 #include "quiche/quic/core/quic_stream.h"
20 #include "quiche/quic/core/quic_types.h"
21 #include "quiche/quic/platform/api/quic_export.h"
22 
23 namespace quic {
24 
25 class CachedNetworkParameters;
26 class QuicSession;
27 
28 // Crypto handshake messages in QUIC take place over a reserved stream with the
29 // id 1.  Each endpoint (client and server) will allocate an instance of a
30 // subclass of QuicCryptoStream to send and receive handshake messages.  (In the
31 // normal 1-RTT handshake, the client will send a client hello, CHLO, message.
32 // The server will receive this message and respond with a server hello message,
33 // SHLO.  At this point both sides will have established a crypto context they
34 // can use to send encrypted messages.
35 //
36 // For more details:
37 // https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit?usp=sharing
38 class QUICHE_EXPORT QuicCryptoStream : public QuicStream {
39  public:
40   explicit QuicCryptoStream(QuicSession* session);
41   QuicCryptoStream(const QuicCryptoStream&) = delete;
42   QuicCryptoStream& operator=(const QuicCryptoStream&) = delete;
43 
44   ~QuicCryptoStream() override;
45 
46   // Returns the per-packet framing overhead associated with sending a
47   // handshake message for |version|.
48   static QuicByteCount CryptoMessageFramingOverhead(
49       QuicTransportVersion version, QuicConnectionId connection_id);
50 
51   // QuicStream implementation
52   void OnStreamFrame(const QuicStreamFrame& frame) override;
53   void OnDataAvailable() override;
54 
55   // Called when a CRYPTO frame is received.
56   void OnCryptoFrame(const QuicCryptoFrame& frame);
57 
58   // Called when a CRYPTO frame is ACKed.
59   bool OnCryptoFrameAcked(const QuicCryptoFrame& frame,
60                           QuicTime::Delta ack_delay_time);
61 
62   void OnStreamReset(const QuicRstStreamFrame& frame) override;
63 
64   // Performs key extraction to derive a new secret of |result_len| bytes
65   // dependent on |label|, |context|, and the stream's negotiated subkey secret.
66   // Returns false if the handshake has not been confirmed or the parameters are
67   // invalid (e.g. |label| contains null bytes); returns true on success. This
68   // method is only supported for IETF QUIC and MUST NOT be called in gQUIC as
69   // that'll trigger an assert in DEBUG build.
70   virtual bool ExportKeyingMaterial(absl::string_view label,
71                                     absl::string_view context,
72                                     size_t result_len, std::string* result) = 0;
73 
74   // Writes |data| to the QuicStream at level |level|.
75   virtual void WriteCryptoData(EncryptionLevel level, absl::string_view data);
76 
77   // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
78   // rejected. Note that the value returned by this function may vary during the
79   // handshake. Once |one_rtt_keys_available| returns true, the value returned
80   // by this function will not change for the rest of the lifetime of the
81   // QuicCryptoStream.
82   virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
83 
84   // Returns true once an encrypter has been set for the connection.
85   virtual bool encryption_established() const = 0;
86 
87   // Returns true once the crypto handshake has completed.
88   virtual bool one_rtt_keys_available() const = 0;
89 
90   // Returns the parameters negotiated in the crypto handshake.
91   virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
92       const = 0;
93 
94   // Provides the message parser to use when data is received on this stream.
95   virtual CryptoMessageParser* crypto_message_parser() = 0;
96 
97   // Called when a packet of encryption |level| has been successfully decrypted.
98   virtual void OnPacketDecrypted(EncryptionLevel level) = 0;
99 
100   // Called when a 1RTT packet has been acknowledged.
101   virtual void OnOneRttPacketAcknowledged() = 0;
102 
103   // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
104   virtual void OnHandshakePacketSent() = 0;
105 
106   // Called when a handshake done frame has been received.
107   virtual void OnHandshakeDoneReceived() = 0;
108 
109   // Called when a new token frame has been received.
110   virtual void OnNewTokenReceived(absl::string_view token) = 0;
111 
112   // Called to get an address token.
113   virtual std::string GetAddressToken(
114       const CachedNetworkParameters* cached_network_params) const = 0;
115 
116   // Called to validate |token|.
117   virtual bool ValidateAddressToken(absl::string_view token) const = 0;
118 
119   // Get the last CachedNetworkParameters received from a valid address token.
120   virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
121       const = 0;
122 
123   // Set the CachedNetworkParameters that will be returned by
124   // PreviousCachedNetworkParams.
125   // TODO(wub): This function is test only, move it to a test only library.
126   virtual void SetPreviousCachedNetworkParams(
127       CachedNetworkParameters cached_network_params) = 0;
128 
129   // Returns current handshake state.
130   virtual HandshakeState GetHandshakeState() const = 0;
131 
132   // Called to provide the server-side application state that must be checked
133   // when performing a 0-RTT TLS resumption.
134   //
135   // On a client, this may be called at any time; 0-RTT tickets will not be
136   // cached until this function is called. When a 0-RTT resumption is attempted,
137   // QuicSession::SetApplicationState will be called with the state provided by
138   // a call to this function on a previous connection.
139   //
140   // On a server, this function must be called before commencing the handshake,
141   // otherwise 0-RTT tickets will not be issued. On subsequent connections,
142   // 0-RTT will be rejected if the data passed into this function does not match
143   // the data passed in on the connection where the 0-RTT ticket was issued.
144   virtual void SetServerApplicationStateForResumption(
145       std::unique_ptr<ApplicationState> state) = 0;
146 
147   // Returns the maximum number of bytes that can be buffered at a particular
148   // encryption level |level|.
149   virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const;
150 
151   // Called to generate a decrypter for the next key phase. Each call should
152   // generate the key for phase n+1.
153   virtual std::unique_ptr<QuicDecrypter>
154   AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
155 
156   // Called to generate an encrypter for the same key phase of the last
157   // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
158   virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
159 
160   // Return the SSL struct object created by BoringSSL if the stream is using
161   // TLS1.3. Otherwise, return nullptr.
162   // This method is used in Envoy.
163   virtual SSL* GetSsl() const = 0;
164 
165   // Called to cancel retransmission of unencrypted crypto stream data.
166   void NeuterUnencryptedStreamData();
167 
168   // Called to cancel retransmission of data of encryption |level|.
169   void NeuterStreamDataOfEncryptionLevel(EncryptionLevel level);
170 
171   // Override to record the encryption level of consumed data.
172   void OnStreamDataConsumed(QuicByteCount bytes_consumed) override;
173 
174   // Returns whether there are any bytes pending retransmission in CRYPTO
175   // frames.
176   virtual bool HasPendingCryptoRetransmission() const;
177 
178   // Writes any pending CRYPTO frame retransmissions.
179   void WritePendingCryptoRetransmission();
180 
181   // Override to retransmit lost crypto data with the appropriate encryption
182   // level.
183   void WritePendingRetransmission() override;
184 
185   // Override to send unacked crypto data with the appropriate encryption level.
186   bool RetransmitStreamData(QuicStreamOffset offset, QuicByteCount data_length,
187                             bool fin, TransmissionType type) override;
188 
189   // Sends stream retransmission data at |encryption_level|.
190   QuicConsumedData RetransmitStreamDataAtLevel(
191       QuicStreamOffset retransmission_offset,
192       QuicByteCount retransmission_length, EncryptionLevel encryption_level,
193       TransmissionType type);
194 
195   // Returns the number of bytes of handshake data that have been received from
196   // the peer in either CRYPTO or STREAM frames.
197   uint64_t crypto_bytes_read() const;
198 
199   // Returns the number of bytes of handshake data that have been received from
200   // the peer in CRYPTO frames at a particular encryption level.
201   QuicByteCount BytesReadOnLevel(EncryptionLevel level) const;
202 
203   // Returns the number of bytes of handshake data that have been sent to
204   // the peer in CRYPTO frames at a particular encryption level.
205   QuicByteCount BytesSentOnLevel(EncryptionLevel level) const;
206 
207   // Writes |data_length| of data of a crypto frame to |writer|. The data
208   // written is from the send buffer for encryption level |level| and starts at
209   // |offset|.
210   bool WriteCryptoFrame(EncryptionLevel level, QuicStreamOffset offset,
211                         QuicByteCount data_length, QuicDataWriter* writer);
212 
213   // Called when data from a CRYPTO frame is considered lost. The lost data is
214   // identified by the encryption level, offset, and length in |crypto_frame|.
215   void OnCryptoFrameLost(QuicCryptoFrame* crypto_frame);
216 
217   // Called to retransmit any outstanding data in the range indicated by the
218   // encryption level, offset, and length in |crypto_frame|. Returns true if all
219   // data gets retransmitted.
220   bool RetransmitData(QuicCryptoFrame* crypto_frame, TransmissionType type);
221 
222   // Called to write buffered crypto frames.
223   void WriteBufferedCryptoFrames();
224 
225   // Returns true if there is buffered crypto frames.
226   bool HasBufferedCryptoFrames() const;
227 
228   // Returns true if any portion of the data at encryption level |level|
229   // starting at |offset| for |length| bytes is outstanding.
230   bool IsFrameOutstanding(EncryptionLevel level, size_t offset,
231                           size_t length) const;
232 
233   // Returns true if the crypto handshake is still waiting for acks of sent
234   // data, and false if all data has been acked.
235   bool IsWaitingForAcks() const;
236 
237   // Helper method for OnDataAvailable. Calls CryptoMessageParser::ProcessInput
238   // with the data available in |sequencer| and |level|, and marks the data
239   // passed to ProcessInput as consumed.
240   virtual void OnDataAvailableInSequencer(QuicStreamSequencer* sequencer,
241                                           EncryptionLevel level);
242 
GetStreamSequencerForPacketNumberSpace(PacketNumberSpace packet_number_space)243   QuicStreamSequencer* GetStreamSequencerForPacketNumberSpace(
244       PacketNumberSpace packet_number_space) {
245     return &substreams_[packet_number_space].sequencer;
246   }
247 
248   // Called by OnCryptoFrame to check if a CRYPTO frame is received at an
249   // expected `level`.
250   virtual bool IsCryptoFrameExpectedForEncryptionLevel(
251       EncryptionLevel level) const = 0;
252 
253   // Called to determine the encryption level to send/retransmit crypto data.
254   virtual EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
255       PacketNumberSpace space) const = 0;
256 
257  private:
258   // Data sent and received in CRYPTO frames is sent at multiple packet number
259   // spaces. Some of the state for the single logical crypto stream is split
260   // across packet number spaces, and a CryptoSubstream is used to manage that
261   // state for a particular packet number space.
262   struct QUICHE_EXPORT CryptoSubstream {
263     CryptoSubstream(QuicCryptoStream* crypto_stream);
264 
265     QuicStreamSequencer sequencer;
266     QuicStreamSendBuffer send_buffer;
267   };
268 
269   // Consumed data according to encryption levels.
270   // TODO(fayang): This is not needed once switching from QUIC crypto to
271   // TLS 1.3, which never encrypts crypto data.
272   QuicIntervalSet<QuicStreamOffset> bytes_consumed_[NUM_ENCRYPTION_LEVELS];
273 
274   // Keeps state for data sent/received in CRYPTO frames at each packet number
275   // space;
276   std::array<CryptoSubstream, NUM_PACKET_NUMBER_SPACES> substreams_;
277 };
278 
279 }  // namespace quic
280 
281 #endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_STREAM_H_
282