blob: be99fb2b9495e5d0d7d1648856859533314b52b3 [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_CLIENT_STREAM_H_
6#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_
7
8#include <cstdint>
9#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#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"
renjietangf21e3852020-04-13 15:45:39 -070019#include "net/third_party/quiche/src/quic/core/quic_versions.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
nharper1e32f4f2020-04-20 12:23:01 -070024namespace test {
25class QuicCryptoClientStreamPeer;
26} // namespace test
27
QUICHE teama6ef0a62019-03-07 20:34:33 -050028class QUIC_EXPORT_PRIVATE QuicCryptoClientStreamBase : public QuicCryptoStream {
29 public:
30 explicit QuicCryptoClientStreamBase(QuicSession* session);
31
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
nharper4084fc92020-02-10 14:43:35 -080038 // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
39 // ReceivedInchoateReject instead.
40 //
QUICHE teama6ef0a62019-03-07 20:34:33 -050041 // 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
nharper02703962019-11-07 12:23:13 -080046 // 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
nharper4084fc92020-02-10 14:43:35 -080053 // 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
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 // 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
68class QUIC_EXPORT_PRIVATE QuicCryptoClientStream
69 : public QuicCryptoClientStreamBase {
70 public:
71 // kMaxClientHellos is the maximum number of times that we'll send a client
QUICHE team8b353f32019-04-09 13:49:10 -070072 // hello. The value 4 accounts for:
QUICHE teama6ef0a62019-03-07 20:34:33 -050073 // * 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.
QUICHE team8b353f32019-04-09 13:49:10 -070077 // * 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;
QUICHE teama6ef0a62019-03-07 20:34:33 -050081
rch85240a12019-12-23 11:51:59 -080082 // QuicCryptoClientStream creates a HandshakerInterface at construction time
QUICHE teama6ef0a62019-03-07 20:34:33 -050083 // based on the QuicTransportVersion of the connection. Different
rch85240a12019-12-23 11:51:59 -080084 // HandshakerInterfaces provide implementations of different crypto handshake
QUICHE teama6ef0a62019-03-07 20:34:33 -050085 // protocols. Currently QUIC crypto is the only protocol implemented; a future
rch85240a12019-12-23 11:51:59 -080086 // HandshakerInterface will use TLS as the handshake protocol.
QUICHE teama6ef0a62019-03-07 20:34:33 -050087 // QuicCryptoClientStream delegates all of its public methods to its
rch85240a12019-12-23 11:51:59 -080088 // HandshakerInterface.
QUICHE teama6ef0a62019-03-07 20:34:33 -050089 //
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.
rch85240a12019-12-23 11:51:59 -080093 class QUIC_EXPORT_PRIVATE HandshakerInterface {
QUICHE teama6ef0a62019-03-07 20:34:33 -050094 public:
rch85240a12019-12-23 11:51:59 -080095 virtual ~HandshakerInterface() {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050096
97 // Performs a crypto handshake with the server. Returns true if the
98 // connection is still connected.
99 virtual bool CryptoConnect() = 0;
100
nharper4084fc92020-02-10 14:43:35 -0800101 // DEPRECATED: Use IsResumption, EarlyDataAccepted, and/or
102 // ReceivedInchoateReject instead.
103 //
QUICHE teama6ef0a62019-03-07 20:34:33 -0500104 // 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
nharper02703962019-11-07 12:23:13 -0800109 // 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
nharper4084fc92020-02-10 14:43:35 -0800116 // Returns true if early data (0-RTT) was accepted in the connection.
117 virtual bool EarlyDataAccepted() const = 0;
118
119 // Returns true if the client received an inchoate REJ during the handshake,
120 // extending the handshake by one round trip. This only applies for QUIC
121 // crypto handshakes. The equivalent feature in IETF QUIC is a Retry packet,
122 // but that is handled at the connection layer instead of the crypto layer.
123 virtual bool ReceivedInchoateReject() const = 0;
124
QUICHE teama6ef0a62019-03-07 20:34:33 -0500125 // The number of server config update messages received by the
126 // client. Does not count update messages that were received prior
127 // to handshake confirmation.
128 virtual int num_scup_messages_received() const = 0;
129
vasilvvc48c8712019-03-11 13:38:16 -0700130 virtual std::string chlo_hash() const = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500131
132 // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
133 // for the connection.
134 virtual bool encryption_established() const = 0;
135
fayang685367a2020-01-14 10:40:15 -0800136 // Returns true once 1RTT keys are available.
137 virtual bool one_rtt_keys_available() const = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138
139 // Returns the parameters negotiated in the crypto handshake.
140 virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
141 const = 0;
142
143 // Used by QuicCryptoStream to parse data received on this stream.
144 virtual CryptoMessageParser* crypto_message_parser() = 0;
nharper486a8a92019-08-28 16:25:10 -0700145
146 // Used by QuicCryptoStream to know how much unprocessed data can be
147 // buffered at each encryption level.
148 virtual size_t BufferSizeLimitForLevel(EncryptionLevel level) const = 0;
fayang9a863cf2020-01-16 14:12:11 -0800149
150 // Returns current handshake state.
151 virtual HandshakeState GetHandshakeState() const = 0;
fayang01062942020-01-22 07:23:23 -0800152
fayang2f2915d2020-01-24 06:47:15 -0800153 // Called when a 1RTT packet has been acknowledged.
154 virtual void OnOneRttPacketAcknowledged() = 0;
155
fayang44ae4e92020-04-28 13:09:42 -0700156 // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
157 virtual void OnHandshakePacketSent() = 0;
158
fayanga6a85a82020-05-04 08:58:53 -0700159 // Called when connection gets closed.
160 virtual void OnConnectionClosed(QuicErrorCode error,
161 ConnectionCloseSource source) = 0;
162
fayang01062942020-01-22 07:23:23 -0800163 // Called when handshake done has been received.
164 virtual void OnHandshakeDoneReceived() = 0;
renjietangf21e3852020-04-13 15:45:39 -0700165
166 // Called when application state is received.
nharperac52a862020-06-08 12:41:06 -0700167 virtual void SetServerApplicationStateForResumption(
renjietangf21e3852020-04-13 15:45:39 -0700168 std::unique_ptr<ApplicationState> application_state) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500169 };
170
171 // ProofHandler is an interface that handles callbacks from the crypto
172 // stream when the client has proof verification details of the server.
173 class QUIC_EXPORT_PRIVATE ProofHandler {
174 public:
175 virtual ~ProofHandler() {}
176
177 // Called when the proof in |cached| is marked valid. If this is a secure
178 // QUIC session, then this will happen only after the proof verifier
179 // completes.
180 virtual void OnProofValid(
181 const QuicCryptoClientConfig::CachedState& cached) = 0;
182
183 // Called when proof verification details become available, either because
184 // proof verification is complete, or when cached details are used. This
185 // will only be called for secure QUIC connections.
186 virtual void OnProofVerifyDetailsAvailable(
187 const ProofVerifyDetails& verify_details) = 0;
188 };
189
190 QuicCryptoClientStream(const QuicServerId& server_id,
191 QuicSession* session,
192 std::unique_ptr<ProofVerifyContext> verify_context,
193 QuicCryptoClientConfig* crypto_config,
renjietangbcc066a2020-04-21 18:05:57 -0700194 ProofHandler* proof_handler,
195 bool has_application_state);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500196 QuicCryptoClientStream(const QuicCryptoClientStream&) = delete;
197 QuicCryptoClientStream& operator=(const QuicCryptoClientStream&) = delete;
198
199 ~QuicCryptoClientStream() override;
200
201 // From QuicCryptoClientStreamBase
202 bool CryptoConnect() override;
203 int num_sent_client_hellos() const override;
nharper02703962019-11-07 12:23:13 -0800204 bool IsResumption() const override;
nharper4084fc92020-02-10 14:43:35 -0800205 bool EarlyDataAccepted() const override;
206 bool ReceivedInchoateReject() const override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207
208 int num_scup_messages_received() const override;
209
210 // From QuicCryptoStream
211 bool encryption_established() const override;
fayang685367a2020-01-14 10:40:15 -0800212 bool one_rtt_keys_available() const override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
214 const override;
215 CryptoMessageParser* crypto_message_parser() override;
fayangd58736d2019-11-27 13:35:31 -0800216 void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
fayang2f2915d2020-01-24 06:47:15 -0800217 void OnOneRttPacketAcknowledged() override;
fayang44ae4e92020-04-28 13:09:42 -0700218 void OnHandshakePacketSent() override;
fayanga6a85a82020-05-04 08:58:53 -0700219 void OnConnectionClosed(QuicErrorCode error,
220 ConnectionCloseSource source) override;
fayang01062942020-01-22 07:23:23 -0800221 void OnHandshakeDoneReceived() override;
fayang9a863cf2020-01-16 14:12:11 -0800222 HandshakeState GetHandshakeState() const override;
nharperac52a862020-06-08 12:41:06 -0700223 void SetServerApplicationStateForResumption(
renjietangf21e3852020-04-13 15:45:39 -0700224 std::unique_ptr<ApplicationState> application_state) override;
nharperac52a862020-06-08 12:41:06 -0700225 size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
renjietangf21e3852020-04-13 15:45:39 -0700226
vasilvvc48c8712019-03-11 13:38:16 -0700227 std::string chlo_hash() const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500228
229 protected:
rch85240a12019-12-23 11:51:59 -0800230 void set_handshaker(std::unique_ptr<HandshakerInterface> handshaker) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500231 handshaker_ = std::move(handshaker);
232 }
233
234 private:
nharper1e32f4f2020-04-20 12:23:01 -0700235 friend class test::QuicCryptoClientStreamPeer;
rch85240a12019-12-23 11:51:59 -0800236 std::unique_ptr<HandshakerInterface> handshaker_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500237};
238
239} // namespace quic
240
241#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_STREAM_H_