blob: 8e9ef05597be09743f9edaac888a1f50d15165dc [file] [log] [blame]
Bence Békybac04052022-04-07 15:44:29 -04001// 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_HANDSHAKER_H_
6#define QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_
7
8#include <string>
9
10#include "quiche/quic/core/crypto/proof_verifier.h"
11#include "quiche/quic/core/crypto/quic_crypto_client_config.h"
12#include "quiche/quic/core/quic_crypto_client_stream.h"
13#include "quiche/quic/core/quic_server_id.h"
haoyuewangcc449fc2022-05-09 14:34:57 -070014#include "quiche/quic/core/quic_types.h"
Bence Békybac04052022-04-07 15:44:29 -040015#include "quiche/quic/platform/api/quic_export.h"
16#include "quiche/common/platform/api/quiche_logging.h"
17
18namespace quic {
19
20// An implementation of QuicCryptoClientStream::HandshakerInterface which uses
21// QUIC crypto as the crypto handshake protocol.
vasilvvf326e932023-09-07 11:56:40 -070022class QUICHE_EXPORT QuicCryptoClientHandshaker
Bence Békybac04052022-04-07 15:44:29 -040023 : public QuicCryptoClientStream::HandshakerInterface,
24 public QuicCryptoHandshaker {
25 public:
26 QuicCryptoClientHandshaker(
bnc862751f2022-04-13 08:33:42 -070027 const QuicServerId& server_id, QuicCryptoClientStream* stream,
28 QuicSession* session, std::unique_ptr<ProofVerifyContext> verify_context,
Bence Békybac04052022-04-07 15:44:29 -040029 QuicCryptoClientConfig* crypto_config,
30 QuicCryptoClientStream::ProofHandler* proof_handler);
31 QuicCryptoClientHandshaker(const QuicCryptoClientHandshaker&) = delete;
32 QuicCryptoClientHandshaker& operator=(const QuicCryptoClientHandshaker&) =
33 delete;
34
35 ~QuicCryptoClientHandshaker() override;
36
37 // From QuicCryptoClientStream::HandshakerInterface
38 bool CryptoConnect() override;
39 int num_sent_client_hellos() const override;
wub80343472023-07-07 11:39:51 -070040 bool ResumptionAttempted() const override;
Bence Békybac04052022-04-07 15:44:29 -040041 bool IsResumption() const override;
42 bool EarlyDataAccepted() const override;
43 ssl_early_data_reason_t EarlyDataReason() const override;
44 bool ReceivedInchoateReject() const override;
45 int num_scup_messages_received() const override;
46 std::string chlo_hash() const override;
47 bool encryption_established() const override;
haoyuewang3d173d52022-04-27 12:20:25 -070048 bool IsCryptoFrameExpectedForEncryptionLevel(
49 EncryptionLevel level) const override;
haoyuewangcc449fc2022-05-09 14:34:57 -070050 EncryptionLevel GetEncryptionLevelToSendCryptoDataOfSpace(
51 PacketNumberSpace space) const override;
Bence Békybac04052022-04-07 15:44:29 -040052 bool one_rtt_keys_available() const override;
53 const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
54 const override;
55 CryptoMessageParser* crypto_message_parser() override;
56 HandshakeState GetHandshakeState() const override;
57 size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
58 std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
59 override;
60 std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override;
61 void OnOneRttPacketAcknowledged() override {}
62 void OnHandshakePacketSent() override {}
63 void OnConnectionClosed(QuicErrorCode /*error*/,
64 ConnectionCloseSource /*source*/) override;
65 void OnHandshakeDoneReceived() override;
66 void OnNewTokenReceived(absl::string_view token) override;
67 void SetServerApplicationStateForResumption(
68 std::unique_ptr<ApplicationState> /*application_state*/) override {
69 QUICHE_NOTREACHED();
70 }
71 bool ExportKeyingMaterial(absl::string_view /*label*/,
72 absl::string_view /*context*/,
73 size_t /*result_len*/,
74 std::string* /*result*/) override {
75 QUICHE_NOTREACHED();
76 return false;
77 }
78
79 // From QuicCryptoHandshaker
80 void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
81
82 protected:
83 // Returns the QuicSession that this stream belongs to.
84 QuicSession* session() const { return session_; }
85
86 // Send either InchoateClientHello or ClientHello message to the server.
87 void DoSendCHLO(QuicCryptoClientConfig::CachedState* cached);
88
89 private:
90 // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
91 // The ProofVerifier calls this class with the result of proof verification
92 // when verification is performed asynchronously.
vasilvvf326e932023-09-07 11:56:40 -070093 class QUICHE_EXPORT ProofVerifierCallbackImpl : public ProofVerifierCallback {
Bence Békybac04052022-04-07 15:44:29 -040094 public:
95 explicit ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent);
96 ~ProofVerifierCallbackImpl() override;
97
98 // ProofVerifierCallback interface.
bnc862751f2022-04-13 08:33:42 -070099 void Run(bool ok, const std::string& error_details,
Bence Békybac04052022-04-07 15:44:29 -0400100 std::unique_ptr<ProofVerifyDetails>* details) override;
101
102 // Cancel causes any future callbacks to be ignored. It must be called on
103 // the same thread as the callback will be made on.
104 void Cancel();
105
106 private:
107 QuicCryptoClientHandshaker* parent_;
108 };
109
110 enum State {
111 STATE_IDLE,
112 STATE_INITIALIZE,
113 STATE_SEND_CHLO,
114 STATE_RECV_REJ,
115 STATE_VERIFY_PROOF,
116 STATE_VERIFY_PROOF_COMPLETE,
117 STATE_RECV_SHLO,
118 STATE_INITIALIZE_SCUP,
119 STATE_NONE,
120 STATE_CONNECTION_CLOSED,
121 };
122
123 // Handles new server config and optional source-address token provided by the
124 // server during a connection.
125 void HandleServerConfigUpdateMessage(
126 const CryptoHandshakeMessage& server_config_update);
127
128 // DoHandshakeLoop performs a step of the handshake state machine. Note that
129 // |in| may be nullptr if the call did not result from a received message.
130 void DoHandshakeLoop(const CryptoHandshakeMessage* in);
131
132 // Start the handshake process.
133 void DoInitialize(QuicCryptoClientConfig::CachedState* cached);
134
135 // Process REJ message from the server.
136 void DoReceiveREJ(const CryptoHandshakeMessage* in,
137 QuicCryptoClientConfig::CachedState* cached);
138
139 // Start the proof verification process. Returns the QuicAsyncStatus returned
140 // by the ProofVerifier's VerifyProof.
141 QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
142
143 // If proof is valid then it sets the proof as valid (which persists the
144 // server config). If not, it closes the connection.
145 void DoVerifyProofComplete(QuicCryptoClientConfig::CachedState* cached);
146
147 // Process SHLO message from the server.
148 void DoReceiveSHLO(const CryptoHandshakeMessage* in,
149 QuicCryptoClientConfig::CachedState* cached);
150
151 // Start the proof verification if |server_id_| is https and |cached| has
152 // signature.
153 void DoInitializeServerConfigUpdate(
154 QuicCryptoClientConfig::CachedState* cached);
155
156 // Called to set the proof of |cached| valid. Also invokes the session's
157 // OnProofValid() method.
158 void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);
159
160 QuicCryptoClientStream* stream_;
161
162 QuicSession* session_;
163 HandshakerDelegateInterface* delegate_;
164
165 State next_state_;
166 // num_client_hellos_ contains the number of client hello messages that this
167 // connection has sent.
168 int num_client_hellos_;
169
170 ssl_early_data_reason_t early_data_reason_ = ssl_early_data_unknown;
171
172 QuicCryptoClientConfig* const crypto_config_;
173
174 // SHA-256 hash of the most recently sent CHLO.
175 std::string chlo_hash_;
176
177 // Server's (hostname, port, is_https, privacy_mode) tuple.
178 const QuicServerId server_id_;
179
180 // Generation counter from QuicCryptoClientConfig's CachedState.
181 uint64_t generation_counter_;
182
183 // verify_context_ contains the context object that we pass to asynchronous
184 // proof verifications.
185 std::unique_ptr<ProofVerifyContext> verify_context_;
186
187 // proof_verify_callback_ contains the callback object that we passed to an
188 // asynchronous proof verification. The ProofVerifier owns this object.
189 ProofVerifierCallbackImpl* proof_verify_callback_;
190 // proof_handler_ contains the callback object used by a quic client
191 // for proof verification. It is not owned by this class.
192 QuicCryptoClientStream::ProofHandler* proof_handler_;
193
194 // These members are used to store the result of an asynchronous proof
195 // verification. These members must not be used after
196 // STATE_VERIFY_PROOF_COMPLETE.
197 bool verify_ok_;
198 std::string verify_error_details_;
199 std::unique_ptr<ProofVerifyDetails> verify_details_;
200
201 QuicTime proof_verify_start_time_;
202
203 int num_scup_messages_received_;
204
205 bool encryption_established_;
206 bool one_rtt_keys_available_;
207 quiche::QuicheReferenceCountedPointer<QuicCryptoNegotiatedParameters>
208 crypto_negotiated_params_;
209};
210
211} // namespace quic
212
213#endif // QUICHE_QUIC_CORE_QUIC_CRYPTO_CLIENT_HANDSHAKER_H_