blob: 2bad8ecfdcd2d1e59e69aed04797f391cf9681ad [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
nharper21a32492020-02-28 12:53:17 -08005#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
7#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
vasilvvbed67c62020-10-20 06:38:43 -070010#include "absl/base/macros.h"
vasilvvc872ee42020-10-07 19:50:22 -070011#include "absl/strings/string_view.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "third_party/boringssl/src/include/openssl/sha.h"
wubbe634b72020-06-16 08:41:26 -070013#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080014#include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16namespace quic {
17
nharper21a32492020-02-28 12:53:17 -080018class QuicCryptoServerStream::ProcessClientHelloCallback
QUICHE teama6ef0a62019-03-07 20:34:33 -050019 : public ProcessClientHelloResultCallback {
20 public:
21 ProcessClientHelloCallback(
nharper21a32492020-02-28 12:53:17 -080022 QuicCryptoServerStream* parent,
QUICHE teama6ef0a62019-03-07 20:34:33 -050023 const QuicReferenceCountedPointer<
24 ValidateClientHelloResultCallback::Result>& result)
25 : parent_(parent), result_(result) {}
26
27 void Run(
28 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -070029 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050030 std::unique_ptr<CryptoHandshakeMessage> message,
31 std::unique_ptr<DiversificationNonce> diversification_nonce,
32 std::unique_ptr<ProofSource::Details> proof_source_details) override {
33 if (parent_ == nullptr) {
34 return;
35 }
36
37 parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
38 *result_, error, error_details, std::move(message),
39 std::move(diversification_nonce), std::move(proof_source_details));
40 }
41
42 void Cancel() { parent_ = nullptr; }
43
44 private:
nharper21a32492020-02-28 12:53:17 -080045 QuicCryptoServerStream* parent_;
QUICHE teama6ef0a62019-03-07 20:34:33 -050046 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
47 result_;
48};
49
nharper21a32492020-02-28 12:53:17 -080050QuicCryptoServerStream::QuicCryptoServerStream(
QUICHE teama6ef0a62019-03-07 20:34:33 -050051 const QuicCryptoServerConfig* crypto_config,
QUICHE teama6ef0a62019-03-07 20:34:33 -050052 QuicCompressedCertsCache* compressed_certs_cache,
53 QuicSession* session,
nharper5f23a2d2020-02-20 10:44:09 -080054 QuicCryptoServerStreamBase::Helper* helper)
nharperbb7d1f32020-02-21 17:20:33 -080055 : QuicCryptoServerStreamBase(session),
56 QuicCryptoHandshaker(this, session),
QUICHE teama6ef0a62019-03-07 20:34:33 -050057 session_(session),
fayangd58736d2019-11-27 13:35:31 -080058 delegate_(session),
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 crypto_config_(crypto_config),
60 compressed_certs_cache_(compressed_certs_cache),
61 signed_config_(new QuicSignedServerConfig),
62 helper_(helper),
63 num_handshake_messages_(0),
64 num_handshake_messages_with_server_nonces_(0),
65 send_server_config_update_cb_(nullptr),
66 num_server_config_update_messages_sent_(0),
67 zero_rtt_attempted_(false),
68 chlo_packet_size_(0),
69 validate_client_hello_cb_(nullptr),
70 process_client_hello_cb_(nullptr),
71 encryption_established_(false),
fayang685367a2020-01-14 10:40:15 -080072 one_rtt_keys_available_(false),
fayang9a863cf2020-01-16 14:12:11 -080073 one_rtt_packet_decrypted_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -050074 crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
75
nharper21a32492020-02-28 12:53:17 -080076QuicCryptoServerStream::~QuicCryptoServerStream() {
QUICHE teama6ef0a62019-03-07 20:34:33 -050077 CancelOutstandingCallbacks();
78}
79
nharper21a32492020-02-28 12:53:17 -080080void QuicCryptoServerStream::CancelOutstandingCallbacks() {
QUICHE teama6ef0a62019-03-07 20:34:33 -050081 // Detach from the validation callback. Calling this multiple times is safe.
82 if (validate_client_hello_cb_ != nullptr) {
83 validate_client_hello_cb_->Cancel();
84 validate_client_hello_cb_ = nullptr;
85 }
86 if (send_server_config_update_cb_ != nullptr) {
87 send_server_config_update_cb_->Cancel();
88 send_server_config_update_cb_ = nullptr;
89 }
90 if (process_client_hello_cb_ != nullptr) {
91 process_client_hello_cb_->Cancel();
92 process_client_hello_cb_ = nullptr;
93 }
94}
95
nharper21a32492020-02-28 12:53:17 -080096void QuicCryptoServerStream::OnHandshakeMessage(
QUICHE teama6ef0a62019-03-07 20:34:33 -050097 const CryptoHandshakeMessage& message) {
98 QuicCryptoHandshaker::OnHandshakeMessage(message);
99 ++num_handshake_messages_;
100 chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
101
102 // Do not process handshake messages after the handshake is confirmed.
fayang685367a2020-01-14 10:40:15 -0800103 if (one_rtt_keys_available_) {
nharperbb7d1f32020-02-21 17:20:33 -0800104 OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
105 "Unexpected handshake message from client");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500106 return;
107 }
108
109 if (message.tag() != kCHLO) {
nharperbb7d1f32020-02-21 17:20:33 -0800110 OnUnrecoverableError(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
111 "Handshake packet not CHLO");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112 return;
113 }
114
115 if (validate_client_hello_cb_ != nullptr ||
116 process_client_hello_cb_ != nullptr) {
117 // Already processing some other handshake message. The protocol
118 // does not allow for clients to send multiple handshake messages
119 // before the server has a chance to respond.
nharperbb7d1f32020-02-21 17:20:33 -0800120 OnUnrecoverableError(QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
121 "Unexpected handshake message while processing CHLO");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122 return;
123 }
124
QUICHE team84910bd2019-03-15 07:03:40 -0700125 chlo_hash_ =
126 CryptoUtils::HashHandshakeMessage(message, Perspective::IS_SERVER);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500127
128 std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
129 DCHECK(validate_client_hello_cb_ == nullptr);
130 DCHECK(process_client_hello_cb_ == nullptr);
131 validate_client_hello_cb_ = cb.get();
132 crypto_config_->ValidateClientHello(
danzhd1fc5912020-05-01 15:29:04 -0700133 message, GetClientAddress(), session()->connection()->self_address(),
134 transport_version(), session()->connection()->clock(), signed_config_,
135 std::move(cb));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500136}
137
nharper21a32492020-02-28 12:53:17 -0800138void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
140 result,
141 std::unique_ptr<ProofSource::Details> details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142 // Clear the callback that got us here.
143 DCHECK(validate_client_hello_cb_ != nullptr);
144 DCHECK(process_client_hello_cb_ == nullptr);
145 validate_client_hello_cb_ = nullptr;
146
QUICHE teama6ef0a62019-03-07 20:34:33 -0500147 std::unique_ptr<ProcessClientHelloCallback> cb(
148 new ProcessClientHelloCallback(this, result));
149 process_client_hello_cb_ = cb.get();
150 ProcessClientHello(result, std::move(details), std::move(cb));
151}
152
nharper21a32492020-02-28 12:53:17 -0800153void QuicCryptoServerStream::
QUICHE teama6ef0a62019-03-07 20:34:33 -0500154 FinishProcessingHandshakeMessageAfterProcessClientHello(
155 const ValidateClientHelloResultCallback::Result& result,
156 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -0700157 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500158 std::unique_ptr<CryptoHandshakeMessage> reply,
159 std::unique_ptr<DiversificationNonce> diversification_nonce,
nharper9b0a1af2020-08-07 17:11:29 -0700160 std::unique_ptr<ProofSource::Details> proof_source_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500161 // Clear the callback that got us here.
162 DCHECK(process_client_hello_cb_ != nullptr);
163 DCHECK(validate_client_hello_cb_ == nullptr);
164 process_client_hello_cb_ = nullptr;
nharper9b0a1af2020-08-07 17:11:29 -0700165 proof_source_details_ = std::move(proof_source_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500166
167 const CryptoHandshakeMessage& message = result.client_hello;
168 if (error != QUIC_NO_ERROR) {
nharperbb7d1f32020-02-21 17:20:33 -0800169 OnUnrecoverableError(error, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500170 return;
171 }
172
173 if (reply->tag() != kSHLO) {
nharper3907ac22019-09-25 15:32:28 -0700174 session()->connection()->set_fully_pad_crypto_handshake_packets(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500175 crypto_config_->pad_rej());
fayang9c41f8b2020-10-30 13:13:06 -0700176 // Send REJ in plaintext.
177 SendHandshakeMessage(*reply, ENCRYPTION_INITIAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500178 return;
179 }
180
181 // If we are returning a SHLO then we accepted the handshake. Now
182 // process the negotiated configuration options as part of the
183 // session config.
184 QuicConfig* config = session()->config();
185 OverrideQuicConfigDefaults(config);
vasilvvc48c8712019-03-11 13:38:16 -0700186 std::string process_error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500187 const QuicErrorCode process_error =
188 config->ProcessPeerHello(message, CLIENT, &process_error_details);
189 if (process_error != QUIC_NO_ERROR) {
nharperbb7d1f32020-02-21 17:20:33 -0800190 OnUnrecoverableError(process_error, process_error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500191 return;
192 }
193
194 session()->OnConfigNegotiated();
195
fkastenholzd3a1de92019-05-15 07:00:07 -0700196 config->ToHandshakeMessage(reply.get(), session()->transport_version());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197
198 // Receiving a full CHLO implies the client is prepared to decrypt with
199 // the new server write key. We can start to encrypt with the new server
200 // write key.
201 //
202 // NOTE: the SHLO will be encrypted with the new server write key.
fayang3f7bcbe2020-02-10 11:08:47 -0800203 delegate_->OnNewEncryptionKeyAvailable(
204 ENCRYPTION_ZERO_RTT,
205 std::move(crypto_negotiated_params_->initial_crypters.encrypter));
206 delegate_->OnNewDecryptionKeyAvailable(
fayangd96ecda2020-02-03 08:45:18 -0800207 ENCRYPTION_ZERO_RTT,
208 std::move(crypto_negotiated_params_->initial_crypters.decrypter),
209 /*set_alternative_decrypter=*/false,
fayang3f7bcbe2020-02-10 11:08:47 -0800210 /*latch_once_used=*/false);
fayangd96ecda2020-02-03 08:45:18 -0800211 delegate_->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
212 delegate_->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213 session()->connection()->SetDiversificationNonce(*diversification_nonce);
214
nharper3907ac22019-09-25 15:32:28 -0700215 session()->connection()->set_fully_pad_crypto_handshake_packets(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500216 crypto_config_->pad_shlo());
fayang9c41f8b2020-10-30 13:13:06 -0700217 // Send SHLO in ENCRYPTION_ZERO_RTT.
218 SendHandshakeMessage(*reply, ENCRYPTION_ZERO_RTT);
fayang3f7bcbe2020-02-10 11:08:47 -0800219 delegate_->OnNewEncryptionKeyAvailable(
220 ENCRYPTION_FORWARD_SECURE,
221 std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
222 delegate_->OnNewDecryptionKeyAvailable(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500223 ENCRYPTION_FORWARD_SECURE,
fayangd96ecda2020-02-03 08:45:18 -0800224 std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
225 /*set_alternative_decrypter=*/true,
fayang3f7bcbe2020-02-10 11:08:47 -0800226 /*latch_once_used=*/false);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500227 encryption_established_ = true;
fayang685367a2020-01-14 10:40:15 -0800228 one_rtt_keys_available_ = true;
fayangd96ecda2020-02-03 08:45:18 -0800229 delegate_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
230 delegate_->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500231}
232
nharper21a32492020-02-28 12:53:17 -0800233void QuicCryptoServerStream::SendServerConfigUpdate(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500234 const CachedNetworkParameters* cached_network_params) {
fayang685367a2020-01-14 10:40:15 -0800235 if (!one_rtt_keys_available_) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 return;
237 }
238
239 if (send_server_config_update_cb_ != nullptr) {
240 QUIC_DVLOG(1)
241 << "Skipped server config update since one is already in progress";
242 return;
243 }
244
245 std::unique_ptr<SendServerConfigUpdateCallback> cb(
246 new SendServerConfigUpdateCallback(this));
247 send_server_config_update_cb_ = cb.get();
248
249 crypto_config_->BuildServerConfigUpdateMessage(
renjietangd1d00852019-09-06 10:43:12 -0700250 session()->transport_version(), chlo_hash_,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251 previous_source_address_tokens_, session()->connection()->self_address(),
danzhd1fc5912020-05-01 15:29:04 -0700252 GetClientAddress(), session()->connection()->clock(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 session()->connection()->random_generator(), compressed_certs_cache_,
254 *crypto_negotiated_params_, cached_network_params, std::move(cb));
255}
256
nharper21a32492020-02-28 12:53:17 -0800257QuicCryptoServerStream::SendServerConfigUpdateCallback::
258 SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500259 : parent_(parent) {}
260
nharper21a32492020-02-28 12:53:17 -0800261void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500262 parent_ = nullptr;
263}
264
265// From BuildServerConfigUpdateMessageResultCallback
nharper21a32492020-02-28 12:53:17 -0800266void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267 bool ok,
268 const CryptoHandshakeMessage& message) {
269 if (parent_ == nullptr) {
270 return;
271 }
272 parent_->FinishSendServerConfigUpdate(ok, message);
273}
274
nharper21a32492020-02-28 12:53:17 -0800275void QuicCryptoServerStream::FinishSendServerConfigUpdate(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500276 bool ok,
277 const CryptoHandshakeMessage& message) {
278 // Clear the callback that got us here.
279 DCHECK(send_server_config_update_cb_ != nullptr);
280 send_server_config_update_cb_ = nullptr;
281
282 if (!ok) {
283 QUIC_DVLOG(1) << "Server: Failed to build server config update (SCUP)!";
284 return;
285 }
286
287 QUIC_DVLOG(1) << "Server: Sending server config update: "
288 << message.DebugString();
fayang9c41f8b2020-10-30 13:13:06 -0700289
290 if (!session()->use_write_or_buffer_data_at_level() &&
291 !QuicVersionUsesCryptoFrames(transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500292 const QuicData& data = message.GetSerialized();
vasilvvc872ee42020-10-07 19:50:22 -0700293 WriteOrBufferData(absl::string_view(data.data(), data.length()), false,
294 nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500295 } else {
fayang9c41f8b2020-10-30 13:13:06 -0700296 // Send server config update in ENCRYPTION_FORWARD_SECURE.
297 SendHandshakeMessage(message, ENCRYPTION_FORWARD_SECURE);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500298 }
299
300 ++num_server_config_update_messages_sent_;
301}
302
fayang6098a0a2020-03-13 15:32:10 -0700303bool QuicCryptoServerStream::IsZeroRtt() const {
304 return num_handshake_messages_ == 1 &&
305 num_handshake_messages_with_server_nonces_ == 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500306}
307
nharperfd0e2632020-06-02 11:19:05 -0700308bool QuicCryptoServerStream::IsResumption() const {
309 // QUIC Crypto doesn't have a non-0-RTT resumption mode.
310 return IsZeroRtt();
311}
312
nharper21a32492020-02-28 12:53:17 -0800313int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500314 return num_server_config_update_messages_sent_;
315}
316
317const CachedNetworkParameters*
nharper21a32492020-02-28 12:53:17 -0800318QuicCryptoServerStream::PreviousCachedNetworkParams() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500319 return previous_cached_network_params_.get();
320}
321
nharperfd0e2632020-06-02 11:19:05 -0700322bool QuicCryptoServerStream::ResumptionAttempted() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500323 return zero_rtt_attempted_;
324}
325
nharper21a32492020-02-28 12:53:17 -0800326void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500327 CachedNetworkParameters cached_network_params) {
328 previous_cached_network_params_.reset(
329 new CachedNetworkParameters(cached_network_params));
330}
331
nharper21a32492020-02-28 12:53:17 -0800332void QuicCryptoServerStream::OnPacketDecrypted(EncryptionLevel level) {
fayangd58736d2019-11-27 13:35:31 -0800333 if (level == ENCRYPTION_FORWARD_SECURE) {
fayang9a863cf2020-01-16 14:12:11 -0800334 one_rtt_packet_decrypted_ = true;
fayangd58736d2019-11-27 13:35:31 -0800335 delegate_->NeuterHandshakeData();
336 }
337}
338
nharper21a32492020-02-28 12:53:17 -0800339void QuicCryptoServerStream::OnHandshakeDoneReceived() {
nharperbb7d1f32020-02-21 17:20:33 -0800340 DCHECK(false);
341}
342
nharper21a32492020-02-28 12:53:17 -0800343bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344 return signed_config_->proof.send_expect_ct_header;
345}
346
nharper9b0a1af2020-08-07 17:11:29 -0700347const ProofSource::Details* QuicCryptoServerStream::ProofSourceDetails() const {
348 return proof_source_details_.get();
349}
350
nharper21a32492020-02-28 12:53:17 -0800351bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
vasilvvc48c8712019-03-11 13:38:16 -0700352 std::string* output) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500353 if (!encryption_established() ||
354 crypto_negotiated_params_->channel_id.empty()) {
355 return false;
356 }
357
vasilvvc48c8712019-03-11 13:38:16 -0700358 const std::string& channel_id(crypto_negotiated_params_->channel_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500359 uint8_t digest[SHA256_DIGEST_LENGTH];
360 SHA256(reinterpret_cast<const uint8_t*>(channel_id.data()), channel_id.size(),
361 digest);
362
vasilvvbed67c62020-10-20 06:38:43 -0700363 quiche::QuicheTextUtils::Base64Encode(digest, ABSL_ARRAYSIZE(digest), output);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500364 return true;
365}
366
nharper6a6bd312020-09-17 13:20:53 -0700367ssl_early_data_reason_t QuicCryptoServerStream::EarlyDataReason() const {
368 if (IsZeroRtt()) {
369 return ssl_early_data_accepted;
370 }
371 if (zero_rtt_attempted_) {
372 return ssl_early_data_session_not_resumed;
373 }
374 return ssl_early_data_no_session_offered;
375}
376
nharper21a32492020-02-28 12:53:17 -0800377bool QuicCryptoServerStream::encryption_established() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500378 return encryption_established_;
379}
380
nharper21a32492020-02-28 12:53:17 -0800381bool QuicCryptoServerStream::one_rtt_keys_available() const {
fayang685367a2020-01-14 10:40:15 -0800382 return one_rtt_keys_available_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500383}
384
385const QuicCryptoNegotiatedParameters&
nharper21a32492020-02-28 12:53:17 -0800386QuicCryptoServerStream::crypto_negotiated_params() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500387 return *crypto_negotiated_params_;
388}
389
nharper21a32492020-02-28 12:53:17 -0800390CryptoMessageParser* QuicCryptoServerStream::crypto_message_parser() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500391 return QuicCryptoHandshaker::crypto_message_parser();
392}
393
nharper21a32492020-02-28 12:53:17 -0800394HandshakeState QuicCryptoServerStream::GetHandshakeState() const {
fayang9a863cf2020-01-16 14:12:11 -0800395 return one_rtt_packet_decrypted_ ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
396}
397
nharperac52a862020-06-08 12:41:06 -0700398void QuicCryptoServerStream::SetServerApplicationStateForResumption(
399 std::unique_ptr<ApplicationState> /*state*/) {
400 // QUIC Crypto doesn't need to remember any application state as part of doing
401 // 0-RTT resumption, so this function is a no-op.
402}
403
nharper21a32492020-02-28 12:53:17 -0800404size_t QuicCryptoServerStream::BufferSizeLimitForLevel(
nharper486a8a92019-08-28 16:25:10 -0700405 EncryptionLevel level) const {
406 return QuicCryptoHandshaker::BufferSizeLimitForLevel(level);
407}
408
mattm072a7e32020-10-09 16:16:56 -0700409bool QuicCryptoServerStream::KeyUpdateSupportedLocally() const {
410 return false;
411}
412
413std::unique_ptr<QuicDecrypter>
414QuicCryptoServerStream::AdvanceKeysAndCreateCurrentOneRttDecrypter() {
415 // Key update is only defined in QUIC+TLS.
416 DCHECK(false);
417 return nullptr;
418}
419
420std::unique_ptr<QuicEncrypter>
421QuicCryptoServerStream::CreateCurrentOneRttEncrypter() {
422 // Key update is only defined in QUIC+TLS.
423 DCHECK(false);
424 return nullptr;
425}
426
nharper21a32492020-02-28 12:53:17 -0800427void QuicCryptoServerStream::ProcessClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500428 QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
429 result,
nharper9b0a1af2020-08-07 17:11:29 -0700430 std::unique_ptr<ProofSource::Details> proof_source_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500431 std::unique_ptr<ProcessClientHelloResultCallback> done_cb) {
nharper9b0a1af2020-08-07 17:11:29 -0700432 proof_source_details_ = std::move(proof_source_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500433 const CryptoHandshakeMessage& message = result->client_hello;
vasilvvc48c8712019-03-11 13:38:16 -0700434 std::string error_details;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500435 if (!helper_->CanAcceptClientHello(
436 message, GetClientAddress(), session()->connection()->peer_address(),
437 session()->connection()->self_address(), &error_details)) {
438 done_cb->Run(QUIC_HANDSHAKE_FAILED, error_details, nullptr, nullptr,
439 nullptr);
440 return;
441 }
wubbe634b72020-06-16 08:41:26 -0700442
vasilvvc872ee42020-10-07 19:50:22 -0700443 absl::string_view user_agent_id;
wub13ebfa62020-08-10 07:48:24 -0700444 message.GetStringPiece(quic::kUAID, &user_agent_id);
wub1abb2a12020-08-14 18:06:28 -0700445 if (!session()->user_agent_id().has_value() && !user_agent_id.empty()) {
446 session()->SetUserAgentId(std::string(user_agent_id));
wubbe634b72020-06-16 08:41:26 -0700447 }
448
QUICHE teama6ef0a62019-03-07 20:34:33 -0500449 if (!result->info.server_nonce.empty()) {
450 ++num_handshake_messages_with_server_nonces_;
451 }
452
453 if (num_handshake_messages_ == 1) {
454 // Client attempts zero RTT handshake by sending a non-inchoate CHLO.
vasilvvc872ee42020-10-07 19:50:22 -0700455 absl::string_view public_value;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500456 zero_rtt_attempted_ = message.GetStringPiece(kPUBS, &public_value);
457 }
458
459 // Store the bandwidth estimate from the client.
460 if (result->cached_network_params.bandwidth_estimate_bytes_per_second() > 0) {
461 previous_cached_network_params_.reset(
462 new CachedNetworkParameters(result->cached_network_params));
463 }
464 previous_source_address_tokens_ = result->info.source_address_tokens;
465
QUICHE teama6ef0a62019-03-07 20:34:33 -0500466 QuicConnection* connection = session()->connection();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467 crypto_config_->ProcessClientHello(
468 result, /*reject_only=*/false, connection->connection_id(),
469 connection->self_address(), GetClientAddress(), connection->version(),
wubecf9bd82019-06-05 04:57:02 -0700470 session()->supported_versions(), connection->clock(),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500471 connection->random_generator(), compressed_certs_cache_,
472 crypto_negotiated_params_, signed_config_,
473 QuicCryptoStream::CryptoMessageFramingOverhead(
474 transport_version(), connection->connection_id()),
475 chlo_packet_size_, std::move(done_cb));
476}
477
nharper21a32492020-02-28 12:53:17 -0800478void QuicCryptoServerStream::OverrideQuicConfigDefaults(
dschinazi17d42422019-06-18 16:35:07 -0700479 QuicConfig* /*config*/) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500480
nharper21a32492020-02-28 12:53:17 -0800481QuicCryptoServerStream::ValidateCallback::ValidateCallback(
482 QuicCryptoServerStream* parent)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500483 : parent_(parent) {}
484
nharper21a32492020-02-28 12:53:17 -0800485void QuicCryptoServerStream::ValidateCallback::Cancel() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500486 parent_ = nullptr;
487}
488
nharper21a32492020-02-28 12:53:17 -0800489void QuicCryptoServerStream::ValidateCallback::Run(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500490 QuicReferenceCountedPointer<Result> result,
491 std::unique_ptr<ProofSource::Details> details) {
492 if (parent_ != nullptr) {
493 parent_->FinishProcessingHandshakeMessage(std::move(result),
494 std::move(details));
495 }
496}
497
nharper21a32492020-02-28 12:53:17 -0800498const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500499 return session()->connection()->peer_address();
500}
501
502} // namespace quic