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