xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_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_CLIENT_STREAM_H_
6 #define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
7 
8 #include <cstdint>
9 #include <memory>
10 #include <string>
11 
12 #include "quiche/quic/core/crypto/proof_verifier.h"
13 #include "quiche/quic/core/crypto/quic_crypto_client_config.h"
14 #include "quiche/quic/core/proto/cached_network_parameters_proto.h"
15 #include "quiche/quic/core/quic_config.h"
16 #include "quiche/quic/core/quic_crypto_handshaker.h"
17 #include "quiche/quic/core/quic_crypto_stream.h"
18 #include "quiche/quic/core/quic_server_id.h"
19 #include "quiche/quic/core/quic_session.h"
20 #include "quiche/quic/core/quic_types.h"
21 #include "quiche/quic/core/quic_versions.h"
22 #include "quiche/quic/platform/api/quic_export.h"
23 
24 namespace quic {
25 
26 namespace test {
27 class QuicCryptoClientStreamPeer;
28 }  // namespace test
29 
30 class TlsClientHandshaker;
31 
32 class QUICHE_EXPORT QuicCryptoClientStreamBase : public QuicCryptoStream {
33  public:
34   explicit QuicCryptoClientStreamBase(QuicSession* session);
35 
~QuicCryptoClientStreamBase()36   ~QuicCryptoClientStreamBase() override {}
37 
38   // Performs a crypto handshake with the server. Returns true if the connection
39   // is still connected.
40   virtual bool CryptoConnect() = 0;
41 
42   // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
43   // ReceivedInchoateReject instead.
44   //
45   // num_sent_client_hellos returns the number of client hello messages that
46   // have been sent. If the handshake has completed then this is one greater
47   // than the number of round-trips needed for the handshake.
48   virtual int num_sent_client_hellos() const = 0;
49 
50   // Whether TLS resumption was attempted by this client. IETF QUIC only.
51   virtual bool ResumptionAttempted() const = 0;
52 
53   // Returns true if the handshake performed was a resumption instead of a full
54   // handshake. Resumption only makes sense for TLS handshakes - there is no
55   // concept of resumption for QUIC crypto even though it supports a 0-RTT
56   // handshake. This function only returns valid results once the handshake is
57   // complete.
58   virtual bool IsResumption() const = 0;
59 
60   // Returns true if early data (0-RTT) was accepted in the connection.
61   virtual bool EarlyDataAccepted() const = 0;
62 
63   // Returns true if the client received an inchoate REJ during the handshake,
64   // extending the handshake by one round trip. This only applies for QUIC
65   // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
66   // but that is handled at the connection layer instead of the crypto layer.
67   virtual bool ReceivedInchoateReject() const = 0;
68 
69   // The number of server config update messages received by the
70   // client.  Does not count update messages that were received prior
71   // to handshake confirmation.
72   virtual int num_scup_messages_received() const = 0;
73 
ExportKeyingMaterial(absl::string_view,absl::string_view,size_t,std::string *)74   bool ExportKeyingMaterial(absl::string_view /*label*/,
75                             absl::string_view /*context*/,
76                             size_t /*result_len*/,
77                             std::string* /*result*/) override {
78     QUICHE_NOTREACHED();
79     return false;
80   }
81 
GetAddressToken(const CachedNetworkParameters *)82   std::string GetAddressToken(
83       const CachedNetworkParameters* /*cached_network_params*/) const override {
84     QUICHE_DCHECK(false);
85     return "";
86   }
87 
ValidateAddressToken(absl::string_view)88   bool ValidateAddressToken(absl::string_view /*token*/) const override {
89     QUICHE_DCHECK(false);
90     return false;
91   }
92 
PreviousCachedNetworkParams()93   const CachedNetworkParameters* PreviousCachedNetworkParams() const override {
94     QUICHE_DCHECK(false);
95     return nullptr;
96   }
97 
SetPreviousCachedNetworkParams(CachedNetworkParameters)98   void SetPreviousCachedNetworkParams(
99       CachedNetworkParameters /*cached_network_params*/) override {
100     QUICHE_DCHECK(false);
101   }
102 };
103 
104 class QUICHE_EXPORT QuicCryptoClientStream : public QuicCryptoClientStreamBase {
105  public:
106   // kMaxClientHellos is the maximum number of times that we'll send a client
107   // hello. The value 4 accounts for:
108   //   * One failure due to an incorrect or missing source-address token.
109   //   * One failure due the server's certificate chain being unavailible and
110   //     the server being unwilling to send it without a valid source-address
111   //     token.
112   //   * One failure due to the ServerConfig private key being located on a
113   //     remote oracle which has become unavailable, forcing the server to send
114   //     the client a fallback ServerConfig.
115   static const int kMaxClientHellos = 4;
116 
117   // QuicCryptoClientStream creates a HandshakerInterface at construction time
118   // based on the QuicTransportVersion of the connection. Different
119   // HandshakerInterfaces provide implementations of different crypto handshake
120   // protocols. Currently QUIC crypto is the only protocol implemented; a future
121   // HandshakerInterface will use TLS as the handshake protocol.
122   // QuicCryptoClientStream delegates all of its public methods to its
123   // HandshakerInterface.
124   //
125   // This setup of the crypto stream delegating its implementation to the
126   // handshaker results in the handshaker reading and writing bytes on the
127   // crypto stream, instead of the handshaker passing the stream bytes to send.
128   class QUICHE_EXPORT HandshakerInterface {
129    public:
~HandshakerInterface()130     virtual ~HandshakerInterface() {}
131 
132     // Performs a crypto handshake with the server. Returns true if the
133     // connection is still connected.
134     virtual bool CryptoConnect() = 0;
135 
136     // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
137     // ReceivedInchoateReject instead.
138     //
139     // num_sent_client_hellos returns the number of client hello messages that
140     // have been sent. If the handshake has completed then this is one greater
141     // than the number of round-trips needed for the handshake.
142     virtual int num_sent_client_hellos() const = 0;
143 
144     // Whether TLS resumption was attempted by this client. IETF QUIC only.
145     virtual bool ResumptionAttempted() const = 0;
146 
147     // Returns true if the handshake performed was a resumption instead of a
148     // full handshake. Resumption only makes sense for TLS handshakes - there is
149     // no concept of resumption for QUIC crypto even though it supports a 0-RTT
150     // handshake. This function only returns valid results once the handshake is
151     // complete.
152     virtual bool IsResumption() const = 0;
153 
154     // Returns true if early data (0-RTT) was accepted in the connection.
155     virtual bool EarlyDataAccepted() const = 0;
156 
157     // Returns the ssl_early_data_reason_t describing why 0-RTT was accepted or
158     // rejected.
159     virtual ssl_early_data_reason_t EarlyDataReason() const = 0;
160 
161     // Returns true if the client received an inchoate REJ during the handshake,
162     // extending the handshake by one round trip. This only applies for QUIC
163     // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
164     // but that is handled at the connection layer instead of the crypto layer.
165     virtual bool ReceivedInchoateReject() const = 0;
166 
167     // The number of server config update messages received by the
168     // client.  Does not count update messages that were received prior
169     // to handshake confirmation.
170     virtual int num_scup_messages_received() const = 0;
171 
172     virtual std::string chlo_hash() const = 0;
173 
174     // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
175     // for the connection.
176     virtual bool encryption_established() const = 0;
177 
178     // Returns true if receiving CRYPTO_FRAME at encryption `level` is expected.
179     virtual bool IsCryptoFrameExpectedForEncryptionLevel(
180         EncryptionLevel level) const = 0;
181 
182     // Returns the encryption level to send CRYPTO_FRAME for `space`.
183     virtual EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
184         PacketNumberSpace space) const = 0;
185 
186     // Returns true once 1RTT keys are available.
187     virtual bool one_rtt_keys_available() const = 0;
188 
189     // Returns the parameters negotiated in the crypto handshake.
190     virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
191         const = 0;
192 
193     // Used by QuicCryptoStream to parse data received on this stream.
194     virtual CryptoMessageParser* crypto_message_parser() = 0;
195 
196     // Used by QuicCryptoStream to know how much unprocessed data can be
197     // buffered at each encryption level.
198     virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
199 
200     // Called to generate a decrypter for the next key phase. Each call should
201     // generate the key for phase n+1.
202     virtual std::unique_ptr<QuicDecrypter>
203     AdvanceKeysAndCreateCurrentOneRttDecrypter() = 0;
204 
205     // Called to generate an encrypter for the same key phase of the last
206     // decrypter returned by AdvanceKeysAndCreateCurrentOneRttDecrypter().
207     virtual std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() = 0;
208 
209     // Returns current handshake state.
210     virtual HandshakeState GetHandshakeState() const = 0;
211 
212     // Called when a 1RTT packet has been acknowledged.
213     virtual void OnOneRttPacketAcknowledged() = 0;
214 
215     // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
216     virtual void OnHandshakePacketSent() = 0;
217 
218     // Called when connection gets closed.
219     virtual void OnConnectionClosed(QuicErrorCode error,
220                                     ConnectionCloseSource source) = 0;
221 
222     // Called when handshake done has been received.
223     virtual void OnHandshakeDoneReceived() = 0;
224 
225     // Called when new token has been received.
226     virtual void OnNewTokenReceived(absl::string_view token) = 0;
227 
228     // Called when application state is received.
229     virtual void SetServerApplicationStateForResumption(
230         std::unique_ptr<ApplicationState> application_state) = 0;
231 
232     // Called to obtain keying material export of length |result_len| with the
233     // given |label| and |context|. Returns false on failure.
234     virtual bool ExportKeyingMaterial(absl::string_view label,
235                                       absl::string_view context,
236                                       size_t result_len,
237                                       std::string* result) = 0;
238   };
239 
240   // ProofHandler is an interface that handles callbacks from the crypto
241   // stream when the client has proof verification details of the server.
242   class QUICHE_EXPORT ProofHandler {
243    public:
~ProofHandler()244     virtual ~ProofHandler() {}
245 
246     // Called when the proof in |cached| is marked valid.  If this is a secure
247     // QUIC session, then this will happen only after the proof verifier
248     // completes.
249     virtual void OnProofValid(
250         const QuicCryptoClientConfig::CachedState& cached) = 0;
251 
252     // Called when proof verification details become available, either because
253     // proof verification is complete, or when cached details are used. This
254     // will only be called for secure QUIC connections.
255     virtual void OnProofVerifyDetailsAvailable(
256         const ProofVerifyDetails& verify_details) = 0;
257   };
258 
259   QuicCryptoClientStream(const QuicServerId& server_id, QuicSession* session,
260                          std::unique_ptr<ProofVerifyContext> verify_context,
261                          QuicCryptoClientConfig* crypto_config,
262                          ProofHandler* proof_handler,
263                          bool has_application_state);
264   QuicCryptoClientStream(const QuicCryptoClientStream&) = delete;
265   QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete;
266 
267   ~QuicCryptoClientStream() override;
268 
269   // From QuicCryptoClientStreamBase
270   bool CryptoConnect() override;
271   int num_sent_client_hellos() const override;
272   bool ResumptionAttempted() const override;
273   bool IsResumption() const override;
274   bool EarlyDataAccepted() const override;
275   ssl_early_data_reason_t EarlyDataReason() const override;
276   bool ReceivedInchoateReject() const override;
277 
278   int num_scup_messages_received() const override;
279 
280   // From QuicCryptoStream
281   bool encryption_established() const override;
282   bool one_rtt_keys_available() const override;
283   const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
284       const override;
285   CryptoMessageParser* crypto_message_parser() override;
OnPacketDecrypted(EncryptionLevel)286   void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
287   void OnOneRttPacketAcknowledged() override;
288   void OnHandshakePacketSent() override;
289   void OnConnectionClosed(QuicErrorCode error,
290                           ConnectionCloseSource source) override;
291   void OnHandshakeDoneReceived() override;
292   void OnNewTokenReceived(absl::string_view token) override;
293   HandshakeState GetHandshakeState() const override;
294   void SetServerApplicationStateForResumption(
295       std::unique_ptr<ApplicationState> application_state) override;
296   size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
297   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
298       override;
299   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
300   SSL* GetSsl() const override;
301   bool IsCryptoFrameExpectedForEncryptionLevel(
302       EncryptionLevel level) const override;
303   EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
304       PacketNumberSpace space) const override;
305 
306   bool ExportKeyingMaterial(absl::string_view label, absl::string_view context,
307                             size_t result_len, std::string* result) override;
308   std::string chlo_hash() const;
309 
310  protected:
set_handshaker(std::unique_ptr<HandshakerInterface> handshaker)311   void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) {
312     handshaker_ = std::move(handshaker);
313   }
314 
315  private:
316   friend class test::QuicCryptoClientStreamPeer;
317   std::unique_ptr<HandshakerInterface> handshaker_;
318   // Points to |handshaker_| if it uses TLS1.3. Otherwise, nullptr.
319   // TODO(danzh) change the type of |handshaker_| to TlsClientHandshaker after
320   // deprecating Google QUIC.
321   TlsClientHandshaker* tls_handshaker_{nullptr};
322 };
323 
324 }  // namespace quic
325 
326 #endif  // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
327