Index: net/quic/core/crypto/quic_crypto_server_config.cc |
diff --git a/net/quic/core/crypto/quic_crypto_server_config.cc b/net/quic/core/crypto/quic_crypto_server_config.cc |
index dcc925f3920ca14b2a86b635bc7779a2df15a265..8ff8bc771d01f9e057f57b6e959fdd7fa9c2e786 100644 |
--- a/net/quic/core/crypto/quic_crypto_server_config.cc |
+++ b/net/quic/core/crypto/quic_crypto_server_config.cc |
@@ -26,14 +26,11 @@ |
#include "net/quic/core/crypto/curve25519_key_exchange.h" |
#include "net/quic/core/crypto/ephemeral_key_source.h" |
#include "net/quic/core/crypto/key_exchange.h" |
-#include "net/quic/core/crypto/local_strike_register_client.h" |
#include "net/quic/core/crypto/p256_key_exchange.h" |
#include "net/quic/core/crypto/proof_source.h" |
#include "net/quic/core/crypto/quic_decrypter.h" |
#include "net/quic/core/crypto/quic_encrypter.h" |
#include "net/quic/core/crypto/quic_random.h" |
-#include "net/quic/core/crypto/strike_register.h" |
-#include "net/quic/core/crypto/strike_register_client.h" |
#include "net/quic/core/proto/source_address_token.pb.h" |
#include "net/quic/core/quic_bug_tracker.h" |
#include "net/quic/core/quic_clock.h" |
@@ -114,65 +111,6 @@ class ValidateClientHelloHelper { |
DISALLOW_COPY_AND_ASSIGN(ValidateClientHelloHelper); |
}; |
-class VerifyNonceIsValidAndUniqueCallback |
- : public StrikeRegisterClient::ResultCallback { |
- public: |
- VerifyNonceIsValidAndUniqueCallback( |
- scoped_refptr<ValidateClientHelloResultCallback::Result> result, |
- std::unique_ptr<ProofSource::Details> proof_source_details, |
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb) |
- : result_(std::move(result)), |
- proof_source_details_(std::move(proof_source_details)), |
- done_cb_(std::move(done_cb)) {} |
- |
- protected: |
- void RunImpl(bool nonce_is_valid_and_unique, |
- InsertStatus nonce_error) override { |
- DVLOG(1) << "Using client nonce, unique: " << nonce_is_valid_and_unique |
- << " nonce_error: " << nonce_error; |
- if (!nonce_is_valid_and_unique) { |
- HandshakeFailureReason client_nonce_error; |
- switch (nonce_error) { |
- case NONCE_INVALID_FAILURE: |
- client_nonce_error = CLIENT_NONCE_INVALID_FAILURE; |
- break; |
- case NONCE_NOT_UNIQUE_FAILURE: |
- client_nonce_error = CLIENT_NONCE_NOT_UNIQUE_FAILURE; |
- break; |
- case NONCE_INVALID_ORBIT_FAILURE: |
- client_nonce_error = CLIENT_NONCE_INVALID_ORBIT_FAILURE; |
- break; |
- case NONCE_INVALID_TIME_FAILURE: |
- client_nonce_error = CLIENT_NONCE_INVALID_TIME_FAILURE; |
- break; |
- case STRIKE_REGISTER_TIMEOUT: |
- client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_TIMEOUT; |
- break; |
- case STRIKE_REGISTER_FAILURE: |
- client_nonce_error = CLIENT_NONCE_STRIKE_REGISTER_FAILURE; |
- break; |
- case NONCE_UNKNOWN_FAILURE: |
- client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE; |
- break; |
- case NONCE_OK: |
- default: |
- QUIC_BUG << "Unexpected client nonce error: " << nonce_error; |
- client_nonce_error = CLIENT_NONCE_UNKNOWN_FAILURE; |
- break; |
- } |
- result_->info.reject_reasons.push_back(client_nonce_error); |
- } |
- done_cb_->Run(result_, std::move(proof_source_details_)); |
- } |
- |
- private: |
- scoped_refptr<ValidateClientHelloResultCallback::Result> result_; |
- std::unique_ptr<ProofSource::Details> proof_source_details_; |
- std::unique_ptr<ValidateClientHelloResultCallback> done_cb_; |
- |
- DISALLOW_COPY_AND_ASSIGN(VerifyNonceIsValidAndUniqueCallback); |
-}; |
- |
// static |
const char QuicCryptoServerConfig::TESTING[] = "secret string for testing"; |
@@ -225,15 +163,9 @@ QuicCryptoServerConfig::QuicCryptoServerConfig( |
configs_lock_(), |
primary_config_(nullptr), |
next_config_promotion_time_(QuicWallTime::Zero()), |
- server_nonce_strike_register_lock_(), |
proof_source_(std::move(proof_source)), |
- strike_register_no_startup_period_(false), |
- strike_register_max_entries_(1 << 10), |
- strike_register_window_secs_(600), |
source_address_token_future_secs_(3600), |
source_address_token_lifetime_secs_(86400), |
- server_nonce_strike_register_max_entries_(1 << 10), |
- server_nonce_strike_register_window_secs_(120), |
enable_serving_sct_(false), |
rejection_observer_(nullptr) { |
DCHECK(proof_source_.get()); |
@@ -414,9 +346,9 @@ CryptoHandshakeMessage* QuicCryptoServerConfig::AddDefaultConfig( |
} |
bool QuicCryptoServerConfig::SetConfigs( |
- const vector<std::unique_ptr<QuicServerConfigProtobuf>>& protobufs, |
+ const std::vector<std::unique_ptr<QuicServerConfigProtobuf>>& protobufs, |
const QuicWallTime now) { |
- vector<scoped_refptr<Config>> parsed_configs; |
+ std::vector<scoped_refptr<Config>> parsed_configs; |
bool ok = true; |
for (auto& protobuf : protobufs) { |
@@ -442,7 +374,7 @@ bool QuicCryptoServerConfig::SetConfigs( |
base::AutoLock locked(configs_lock_); |
ConfigMap new_configs; |
- for (vector<scoped_refptr<Config>>::const_iterator i = |
+ for (std::vector<scoped_refptr<Config>>::const_iterator i = |
parsed_configs.begin(); |
i != parsed_configs.end(); ++i) { |
scoped_refptr<Config> config = *i; |
@@ -500,7 +432,7 @@ void QuicCryptoServerConfig::ValidateClientHello( |
const IPAddress& server_ip, |
QuicVersion version, |
const QuicClock* clock, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
const QuicWallTime now(clock->WallNow()); |
@@ -530,16 +462,16 @@ void QuicCryptoServerConfig::ValidateClientHello( |
requested_config = GetConfigWithScid(requested_scid); |
primary_config = primary_config_; |
- crypto_proof->config = primary_config_; |
+ signed_config->config = primary_config_; |
} |
if (result->error_code == QUIC_NO_ERROR) { |
// QUIC requires a new proof for each CHLO so clear any existing proof. |
- crypto_proof->chain = nullptr; |
- crypto_proof->signature = ""; |
- crypto_proof->cert_sct = ""; |
+ signed_config->chain = nullptr; |
+ signed_config->signature = ""; |
+ signed_config->cert_sct = ""; |
EvaluateClientHello(server_ip, version, requested_config, primary_config, |
- crypto_proof, result, std::move(done_cb)); |
+ signed_config, result, std::move(done_cb)); |
} else { |
done_cb->Run(result, /* details = */ nullptr); |
} |
@@ -597,7 +529,7 @@ class QuicCryptoServerConfig::ProcessClientHelloCallback |
QuicRandom* rand, |
QuicCompressedCertsCache* compressed_certs_cache, |
scoped_refptr<QuicCryptoNegotiatedParameters> params, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
QuicByteCount total_framing_overhead, |
QuicByteCount chlo_packet_size, |
const scoped_refptr<QuicCryptoServerConfig::Config>& requested_config, |
@@ -616,7 +548,7 @@ class QuicCryptoServerConfig::ProcessClientHelloCallback |
rand_(rand), |
compressed_certs_cache_(compressed_certs_cache), |
params_(params), |
- crypto_proof_(crypto_proof), |
+ signed_config_(signed_config), |
total_framing_overhead_(total_framing_overhead), |
chlo_packet_size_(chlo_packet_size), |
requested_config_(requested_config), |
@@ -625,19 +557,19 @@ class QuicCryptoServerConfig::ProcessClientHelloCallback |
void Run(bool ok, |
const scoped_refptr<ProofSource::Chain>& chain, |
- const string& signature, |
- const string& leaf_cert_sct, |
+ const QuicCryptoProof& proof, |
std::unique_ptr<ProofSource::Details> details) override { |
if (ok) { |
- crypto_proof_->chain = chain; |
- crypto_proof_->signature = signature; |
- crypto_proof_->cert_sct = leaf_cert_sct; |
+ signed_config_->chain = chain; |
+ signed_config_->signature = proof.signature; |
+ signed_config_->cert_sct = proof.leaf_cert_scts; |
+ signed_config_->send_expect_ct_header = proof.send_expect_ct_header; |
} |
config_->ProcessClientHelloAfterGetProof( |
!ok, std::move(details), *validate_chlo_result_, reject_only_, |
connection_id_, client_address_, version_, supported_versions_, |
use_stateless_rejects_, server_designated_connection_id_, clock_, rand_, |
- compressed_certs_cache_, params_, crypto_proof_, |
+ compressed_certs_cache_, params_, signed_config_, |
total_framing_overhead_, chlo_packet_size_, requested_config_, |
primary_config_, std::move(done_cb_)); |
} |
@@ -657,7 +589,7 @@ class QuicCryptoServerConfig::ProcessClientHelloCallback |
QuicRandom* const rand_; |
QuicCompressedCertsCache* compressed_certs_cache_; |
scoped_refptr<QuicCryptoNegotiatedParameters> params_; |
- scoped_refptr<QuicCryptoProof> crypto_proof_; |
+ scoped_refptr<QuicSignedServerConfig> signed_config_; |
const QuicByteCount total_framing_overhead_; |
const QuicByteCount chlo_packet_size_; |
const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; |
@@ -680,7 +612,7 @@ void QuicCryptoServerConfig::ProcessClientHello( |
QuicRandom* rand, |
QuicCompressedCertsCache* compressed_certs_cache, |
scoped_refptr<QuicCryptoNegotiatedParameters> params, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
QuicByteCount total_framing_overhead, |
QuicByteCount chlo_packet_size, |
std::unique_ptr<ProcessClientHelloResultCallback> done_cb) const { |
@@ -722,7 +654,7 @@ void QuicCryptoServerConfig::ProcessClientHello( |
// Use the config that the client requested in order to do key-agreement. |
// Otherwise give it a copy of |primary_config_| to use. |
- primary_config = crypto_proof->config; |
+ primary_config = signed_config->config; |
requested_config = GetConfigWithScid(requested_scid); |
} |
} |
@@ -746,7 +678,7 @@ void QuicCryptoServerConfig::ProcessClientHello( |
CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); |
// No need to get a new proof if one was already generated. |
- if (!crypto_proof->chain) { |
+ if (!signed_config->chain) { |
const QuicTag* tag_ptr; |
size_t num_tags; |
QuicTagVector connection_options; |
@@ -759,7 +691,7 @@ void QuicCryptoServerConfig::ProcessClientHello( |
this, validate_chlo_result, reject_only, connection_id, |
client_address, version, supported_versions, |
use_stateless_rejects, server_designated_connection_id, clock, |
- rand, compressed_certs_cache, params, crypto_proof, |
+ rand, compressed_certs_cache, params, signed_config, |
total_framing_overhead, chlo_packet_size, requested_config, |
primary_config, std::move(done_cb))); |
proof_source_->GetProof(server_ip, info.sni.as_string(), |
@@ -769,13 +701,16 @@ void QuicCryptoServerConfig::ProcessClientHello( |
return; |
} |
- if (!proof_source_->GetProof( |
- server_ip, info.sni.as_string(), primary_config->serialized, |
- version, chlo_hash, connection_options, &crypto_proof->chain, |
- &crypto_proof->signature, &crypto_proof->cert_sct)) { |
+ QuicCryptoProof proof; |
+ if (!proof_source_->GetProof(server_ip, info.sni.as_string(), |
+ primary_config->serialized, version, chlo_hash, |
+ connection_options, &signed_config->chain, |
+ &proof)) { |
helper.Fail(QUIC_HANDSHAKE_FAILED, "Missing or invalid crypto proof."); |
return; |
} |
+ signed_config->signature = proof.signature; |
+ signed_config->cert_sct = proof.leaf_cert_scts; |
} |
helper.DetachCallback(); |
@@ -784,7 +719,7 @@ void QuicCryptoServerConfig::ProcessClientHello( |
*validate_chlo_result, reject_only, connection_id, client_address, |
version, supported_versions, use_stateless_rejects, |
server_designated_connection_id, clock, rand, compressed_certs_cache, |
- params, crypto_proof, total_framing_overhead, chlo_packet_size, |
+ params, signed_config, total_framing_overhead, chlo_packet_size, |
requested_config, primary_config, std::move(done_cb)); |
} |
@@ -803,7 +738,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
QuicRandom* rand, |
QuicCompressedCertsCache* compressed_certs_cache, |
scoped_refptr<QuicCryptoNegotiatedParameters> params, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
QuicByteCount total_framing_overhead, |
QuicByteCount chlo_packet_size, |
const scoped_refptr<Config>& requested_config, |
@@ -833,7 +768,7 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
BuildRejection(version, clock->WallNow(), *primary_config, client_hello, |
info, validate_chlo_result.cached_network_params, |
use_stateless_rejects, server_designated_connection_id, rand, |
- compressed_certs_cache, params, *crypto_proof, |
+ compressed_certs_cache, params, *signed_config, |
total_framing_overhead, chlo_packet_size, out.get()); |
if (FLAGS_quic_export_rej_for_all_rejects && |
rejection_observer_ != nullptr) { |
@@ -864,13 +799,11 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
} |
size_t key_exchange_index; |
- if (!QuicUtils::FindMutualTag(requested_config->aead, their_aeads, |
- num_their_aeads, QuicUtils::LOCAL_PRIORITY, |
- ¶ms->aead, nullptr) || |
- !QuicUtils::FindMutualTag(requested_config->kexs, their_key_exchanges, |
- num_their_key_exchanges, |
- QuicUtils::LOCAL_PRIORITY, |
- ¶ms->key_exchange, &key_exchange_index)) { |
+ if (!FindMutualQuicTag(requested_config->aead, their_aeads, num_their_aeads, |
+ ¶ms->aead, nullptr) || |
+ !FindMutualQuicTag(requested_config->kexs, their_key_exchanges, |
+ num_their_key_exchanges, ¶ms->key_exchange, |
+ &key_exchange_index)) { |
helper.Fail(QUIC_CRYPTO_NO_SUPPORT, "Unsupported AEAD or KEXS"); |
return; |
} |
@@ -882,10 +815,9 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: |
break; |
case QUIC_NO_ERROR: |
- if (QuicUtils::FindMutualTag( |
- requested_config->tb_key_params, their_tbkps, num_their_tbkps, |
- QuicUtils::LOCAL_PRIORITY, ¶ms->token_binding_key_param, |
- nullptr)) { |
+ if (FindMutualQuicTag(requested_config->tb_key_params, their_tbkps, |
+ num_their_tbkps, ¶ms->token_binding_key_param, |
+ nullptr)) { |
break; |
} |
default: |
@@ -926,11 +858,11 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
client_hello_serialized.length()); |
hkdf_suffix.append(requested_config->serialized); |
DCHECK(proof_source_.get()); |
- if (crypto_proof->chain->certs.empty()) { |
+ if (signed_config->chain->certs.empty()) { |
helper.Fail(QUIC_CRYPTO_INTERNAL_ERROR, "Failed to get certs"); |
return; |
} |
- hkdf_suffix.append(crypto_proof->chain->certs.at(0)); |
+ hkdf_suffix.append(signed_config->chain->certs.at(0)); |
StringPiece cetv_ciphertext; |
if (requested_config->channel_id_enabled && |
@@ -998,15 +930,10 @@ void QuicCryptoServerConfig::ProcessClientHelloAfterGetProof( |
hkdf_input.append(QuicCryptoConfig::kInitialLabel, label_len); |
hkdf_input.append(hkdf_suffix); |
+ rand->RandBytes(out_diversification_nonce->data(), |
+ out_diversification_nonce->size()); |
CryptoUtils::Diversification diversification = |
- CryptoUtils::Diversification::Never(); |
- if (version > QUIC_VERSION_32) { |
- rand->RandBytes(out_diversification_nonce->data(), |
- out_diversification_nonce->size()); |
- diversification = |
- CryptoUtils::Diversification::Now(out_diversification_nonce.get()); |
- } |
- |
+ CryptoUtils::Diversification::Now(out_diversification_nonce.get()); |
if (!CryptoUtils::DeriveKeys(params->initial_premaster_secret, params->aead, |
info.client_nonce, info.server_nonce, hkdf_input, |
Perspective::IS_SERVER, diversification, |
@@ -1117,7 +1044,7 @@ bool QuicCryptoServerConfig::ConfigPrimaryTimeLessThan( |
void QuicCryptoServerConfig::SelectNewPrimaryConfig( |
const QuicWallTime now) const { |
- vector<scoped_refptr<Config>> configs; |
+ std::vector<scoped_refptr<Config>> configs; |
configs.reserve(configs_.size()); |
for (ConfigMap::const_iterator it = configs_.begin(); it != configs_.end(); |
@@ -1208,7 +1135,7 @@ class QuicCryptoServerConfig::EvaluateClientHelloCallback |
QuicVersion version, |
scoped_refptr<QuicCryptoServerConfig::Config> requested_config, |
scoped_refptr<QuicCryptoServerConfig::Config> primary_config, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
scoped_refptr<ValidateClientHelloResultCallback::Result> |
client_hello_state, |
std::unique_ptr<ValidateClientHelloResultCallback> done_cb) |
@@ -1218,23 +1145,23 @@ class QuicCryptoServerConfig::EvaluateClientHelloCallback |
version_(version), |
requested_config_(std::move(requested_config)), |
primary_config_(std::move(primary_config)), |
- crypto_proof_(crypto_proof), |
+ signed_config_(signed_config), |
client_hello_state_(std::move(client_hello_state)), |
done_cb_(std::move(done_cb)) {} |
void Run(bool ok, |
const scoped_refptr<ProofSource::Chain>& chain, |
- const string& signature, |
- const string& leaf_cert_sct, |
+ const QuicCryptoProof& proof, |
std::unique_ptr<ProofSource::Details> details) override { |
if (ok) { |
- crypto_proof_->chain = chain; |
- crypto_proof_->signature = signature; |
- crypto_proof_->cert_sct = leaf_cert_sct; |
+ signed_config_->chain = chain; |
+ signed_config_->signature = proof.signature; |
+ signed_config_->cert_sct = proof.leaf_cert_scts; |
+ signed_config_->send_expect_ct_header = proof.send_expect_ct_header; |
} |
config_.EvaluateClientHelloAfterGetProof( |
found_error_, server_ip_, version_, requested_config_, primary_config_, |
- crypto_proof_, std::move(details), !ok, client_hello_state_, |
+ signed_config_, std::move(details), !ok, client_hello_state_, |
std::move(done_cb_)); |
} |
@@ -1245,7 +1172,7 @@ class QuicCryptoServerConfig::EvaluateClientHelloCallback |
const QuicVersion version_; |
const scoped_refptr<QuicCryptoServerConfig::Config> requested_config_; |
const scoped_refptr<QuicCryptoServerConfig::Config> primary_config_; |
- scoped_refptr<QuicCryptoProof> crypto_proof_; |
+ scoped_refptr<QuicSignedServerConfig> signed_config_; |
scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state_; |
std::unique_ptr<ValidateClientHelloResultCallback> done_cb_; |
}; |
@@ -1255,7 +1182,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( |
QuicVersion version, |
scoped_refptr<Config> requested_config, |
scoped_refptr<Config> primary_config, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state, |
std::unique_ptr<ValidateClientHelloResultCallback> done_cb) const { |
ValidateClientHelloHelper helper(client_hello_state, &done_cb); |
@@ -1327,7 +1254,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( |
string chlo_hash; |
CryptoUtils::HashHandshakeMessage(client_hello, &chlo_hash); |
bool need_proof = true; |
- need_proof = !crypto_proof->chain; |
+ need_proof = !signed_config->chain; |
const QuicTag* tag_ptr; |
size_t num_tags; |
QuicTagVector connection_options; |
@@ -1341,7 +1268,7 @@ void QuicCryptoServerConfig::EvaluateClientHello( |
std::unique_ptr<EvaluateClientHelloCallback> cb( |
new EvaluateClientHelloCallback( |
*this, found_error, server_ip, version, requested_config, |
- primary_config, crypto_proof, client_hello_state, |
+ primary_config, signed_config, client_hello_state, |
std::move(done_cb))); |
proof_source_->GetProof(server_ip, info->sni.as_string(), |
serialized_config, version, chlo_hash, |
@@ -1352,19 +1279,24 @@ void QuicCryptoServerConfig::EvaluateClientHello( |
} |
// No need to get a new proof if one was already generated. |
- if (need_proof && |
- !proof_source_->GetProof( |
- server_ip, info->sni.as_string(), serialized_config, version, |
- chlo_hash, connection_options, &crypto_proof->chain, |
- &crypto_proof->signature, &crypto_proof->cert_sct)) { |
- get_proof_failed = true; |
+ if (need_proof) { |
+ QuicCryptoProof proof; |
+ |
+ if (proof_source_->GetProof( |
+ server_ip, info->sni.as_string(), serialized_config, version, |
+ chlo_hash, connection_options, &signed_config->chain, &proof)) { |
+ signed_config->signature = proof.signature; |
+ signed_config->cert_sct = proof.leaf_cert_scts; |
+ } else { |
+ get_proof_failed = true; |
+ } |
} |
// Details are null because the synchronous version of GetProof does not |
// return any stats. Eventually the synchronous codepath will be eliminated. |
EvaluateClientHelloAfterGetProof( |
found_error, server_ip, version, requested_config, primary_config, |
- crypto_proof, nullptr /* proof_source_details */, get_proof_failed, |
+ signed_config, nullptr /* proof_source_details */, get_proof_failed, |
client_hello_state, std::move(done_cb)); |
helper.DetachCallback(); |
} |
@@ -1375,7 +1307,7 @@ void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( |
QuicVersion version, |
scoped_refptr<Config> requested_config, |
scoped_refptr<Config> primary_config, |
- scoped_refptr<QuicCryptoProof> crypto_proof, |
+ scoped_refptr<QuicSignedServerConfig> signed_config, |
std::unique_ptr<ProofSource::Details> proof_source_details, |
bool get_proof_failed, |
scoped_refptr<ValidateClientHelloResultCallback::Result> client_hello_state, |
@@ -1385,12 +1317,10 @@ void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( |
ClientHelloInfo* info = &(client_hello_state->info); |
if (get_proof_failed) { |
- found_error = true; |
info->reject_reasons.push_back(SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE); |
} |
- if (!ValidateExpectedLeafCertificate(client_hello, *crypto_proof)) { |
- found_error = true; |
+ if (!ValidateExpectedLeafCertificate(client_hello, *signed_config)) { |
info->reject_reasons.push_back(INVALID_EXPECTED_LEAF_CERTIFICATE); |
} |
@@ -1399,87 +1329,18 @@ void QuicCryptoServerConfig::EvaluateClientHelloAfterGetProof( |
// Invalid client nonce. |
LOG(ERROR) << "Invalid client nonce: " << client_hello.DebugString(); |
DVLOG(1) << "Invalid client nonce."; |
- found_error = true; |
} |
// Server nonce is optional, and used for key derivation if present. |
client_hello.GetStringPiece(kServerNonceTag, &info->server_nonce); |
- if (version > QUIC_VERSION_32) { |
- DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; |
- // If the server nonce is empty and we're requiring handshake confirmation |
- // for DoS reasons then we must reject the CHLO. |
- if (FLAGS_quic_require_handshake_confirmation && |
- info->server_nonce.empty()) { |
- info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
- } |
- helper.ValidationComplete(QUIC_NO_ERROR, "", |
- std::move(proof_source_details)); |
- return; |
- } |
- |
- if (!replay_protection_) { |
- DVLOG(1) << "No replay protection."; |
- helper.ValidationComplete(QUIC_NO_ERROR, "", |
- std::move(proof_source_details)); |
- return; |
- } |
- |
- if (!info->server_nonce.empty()) { |
- // If the server nonce is present, use it to establish uniqueness. |
- HandshakeFailureReason server_nonce_error = |
- ValidateServerNonce(info->server_nonce, info->now); |
- bool is_unique = server_nonce_error == HANDSHAKE_OK; |
- if (!is_unique) { |
- info->reject_reasons.push_back(server_nonce_error); |
- } |
- DVLOG(1) << "Using server nonce, unique: " << is_unique; |
- helper.ValidationComplete(QUIC_NO_ERROR, "", |
- std::move(proof_source_details)); |
- return; |
- } |
- // If we hit this block, the server nonce was empty. If we're requiring |
- // handshake confirmation for DoS reasons and there's no server nonce present, |
- // reject the CHLO. |
- if (FLAGS_quic_require_handshake_confirmation || |
- FLAGS_quic_require_handshake_confirmation_pre33) { |
- info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
- helper.ValidationComplete(QUIC_NO_ERROR, "", |
- std::move(proof_source_details)); |
- return; |
- } |
- |
- // We want to contact strike register only if there are no errors because it |
- // is a RPC call and is expensive. |
- if (found_error) { |
- helper.ValidationComplete(QUIC_NO_ERROR, "", |
- std::move(proof_source_details)); |
- return; |
- } |
- |
- // Use the client nonce to establish uniqueness. |
- StrikeRegisterClient* strike_register_client; |
- { |
- base::AutoLock locked(strike_register_client_lock_); |
- strike_register_client = strike_register_client_.get(); |
- } |
- |
- if (!strike_register_client) { |
- // Either a valid server nonces or a strike register is required. |
- // Since neither are present, reject the handshake which will send a |
- // server nonce to the client. |
+ DVLOG(1) << "No 0-RTT replay protection in QUIC_VERSION_33 and higher."; |
+ // If the server nonce is empty and we're requiring handshake confirmation |
+ // for DoS reasons then we must reject the CHLO. |
+ if (FLAGS_quic_require_handshake_confirmation && info->server_nonce.empty()) { |
info->reject_reasons.push_back(SERVER_NONCE_REQUIRED_FAILURE); |
- helper.ValidationComplete(QUIC_NO_ERROR, "", |
- std::move(proof_source_details)); |
- return; |
} |
- |
- strike_register_client->VerifyNonceIsValidAndUnique( |
- info->client_nonce, info->now, |
- new VerifyNonceIsValidAndUniqueCallback(client_hello_state, |
- std::move(proof_source_details), |
- std::move(done_cb))); |
- helper.DetachCallback(); |
+ helper.ValidationComplete(QUIC_NO_ERROR, "", std::move(proof_source_details)); |
} |
bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
@@ -1516,11 +1377,9 @@ bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
expiry_time.AbsoluteDifference(clock->WallNow()).ToSeconds()); |
scoped_refptr<ProofSource::Chain> chain; |
- string signature; |
- string cert_sct; |
+ QuicCryptoProof proof; |
if (!proof_source_->GetProof(server_ip, params.sni, serialized, version, |
- chlo_hash, connection_options, &chain, |
- &signature, &cert_sct)) { |
+ chlo_hash, connection_options, &chain, &proof)) { |
DVLOG(1) << "Server: failed to get proof."; |
return false; |
} |
@@ -1530,13 +1389,13 @@ bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage( |
params.client_cached_cert_hashes, common_cert_sets); |
out->SetStringPiece(kCertificateTag, compressed); |
- out->SetStringPiece(kPROF, signature); |
+ out->SetStringPiece(kPROF, proof.signature); |
if (params.sct_supported_by_client && enable_serving_sct_) { |
- if (cert_sct.empty()) { |
+ if (proof.leaf_cert_scts.empty()) { |
DLOG(WARNING) << "SCT is expected but it is empty. sni: " << params.sni |
<< " server_ip: " << server_ip.ToString(); |
} else { |
- out->SetStringPiece(kCertificateSCTTag, cert_sct); |
+ out->SetStringPiece(kCertificateSCTTag, proof.leaf_cert_scts); |
} |
} |
return true; |
@@ -1612,14 +1471,14 @@ QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: |
void QuicCryptoServerConfig::BuildServerConfigUpdateMessageProofSourceCallback:: |
Run(bool ok, |
const scoped_refptr<ProofSource::Chain>& chain, |
- const string& signature, |
- const string& leaf_cert_sct, |
+ const QuicCryptoProof& proof, |
std::unique_ptr<ProofSource::Details> details) { |
config_->FinishBuildServerConfigUpdateMessage( |
version_, compressed_certs_cache_, common_cert_sets_, |
client_common_set_hashes_, client_cached_cert_hashes_, |
- sct_supported_by_client_, ok, chain, signature, leaf_cert_sct, |
- std::move(details), std::move(message_), std::move(cb_)); |
+ sct_supported_by_client_, ok, chain, proof.signature, |
+ proof.leaf_cert_scts, std::move(details), std::move(message_), |
+ std::move(cb_)); |
} |
void QuicCryptoServerConfig::FinishBuildServerConfigUpdateMessage( |
@@ -1670,7 +1529,7 @@ void QuicCryptoServerConfig::BuildRejection( |
QuicRandom* rand, |
QuicCompressedCertsCache* compressed_certs_cache, |
scoped_refptr<QuicCryptoNegotiatedParameters> params, |
- const QuicCryptoProof& crypto_proof, |
+ const QuicSignedServerConfig& signed_config, |
QuicByteCount total_framing_overhead, |
QuicByteCount chlo_packet_size, |
CryptoHandshakeMessage* out) const { |
@@ -1714,7 +1573,7 @@ void QuicCryptoServerConfig::BuildRejection( |
} |
const string compressed = |
- CompressChain(compressed_certs_cache, crypto_proof.chain, |
+ CompressChain(compressed_certs_cache, signed_config.chain, |
params->client_common_set_hashes, |
params->client_cached_cert_hashes, config.common_cert_sets); |
@@ -1737,22 +1596,22 @@ void QuicCryptoServerConfig::BuildRejection( |
"overhead calculation may underflow"); |
bool should_return_sct = |
params->sct_supported_by_client && enable_serving_sct_; |
- const size_t sct_size = should_return_sct ? crypto_proof.cert_sct.size() : 0; |
+ const size_t sct_size = should_return_sct ? signed_config.cert_sct.size() : 0; |
const size_t total_size = |
- crypto_proof.signature.size() + compressed.size() + sct_size; |
+ signed_config.signature.size() + compressed.size() + sct_size; |
if (info.valid_source_address_token || total_size < max_unverified_size) { |
out->SetStringPiece(kCertificateTag, compressed); |
- out->SetStringPiece(kPROF, crypto_proof.signature); |
+ out->SetStringPiece(kPROF, signed_config.signature); |
if (should_return_sct) { |
- if (crypto_proof.cert_sct.empty()) { |
+ if (signed_config.cert_sct.empty()) { |
DLOG(WARNING) << "SCT is expected but it is empty."; |
} else { |
- out->SetStringPiece(kCertificateSCTTag, crypto_proof.cert_sct); |
+ out->SetStringPiece(kCertificateSCTTag, signed_config.cert_sct); |
} |
} |
} else { |
DLOG(WARNING) << "Sending inchoate REJ for hostname: " << info.sni |
- << " signature: " << crypto_proof.signature.size() |
+ << " signature: " << signed_config.signature.size() |
<< " cert: " << compressed.size() << " sct:" << sct_size |
<< " total: " << total_size |
<< " max: " << max_unverified_size; |
@@ -1819,7 +1678,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf( |
LOG(WARNING) << "Server config message is missing AEAD"; |
return nullptr; |
} |
- config->aead = vector<QuicTag>(aead_tags, aead_tags + aead_len); |
+ config->aead = std::vector<QuicTag>(aead_tags, aead_tags + aead_len); |
const QuicTag* kexs_tags; |
size_t kexs_len; |
@@ -1837,7 +1696,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf( |
LOG(WARNING) << "Server config message is missing or has invalid TBKP"; |
return nullptr; |
} |
- config->tb_key_params = vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); |
+ config->tb_key_params = std::vector<QuicTag>(tbkp_tags, tbkp_tags + tbkp_len); |
StringPiece orbit; |
if (!msg->GetStringPiece(kORBT, &orbit)) { |
@@ -1855,22 +1714,6 @@ QuicCryptoServerConfig::ParseConfigProtobuf( |
"orbit has incorrect size"); |
memcpy(config->orbit, orbit.data(), sizeof(config->orbit)); |
- { |
- StrikeRegisterClient* strike_register_client; |
- { |
- base::AutoLock locked(strike_register_client_lock_); |
- strike_register_client = strike_register_client_.get(); |
- } |
- |
- if (strike_register_client != nullptr && |
- !strike_register_client->IsKnownOrbit(orbit)) { |
- LOG(WARNING) |
- << "Rejecting server config with orbit that the strike register " |
- "client doesn't know about."; |
- return nullptr; |
- } |
- } |
- |
if (kexs_len != protobuf->key_size()) { |
LOG(WARNING) << "Server config has " << kexs_len |
<< " key exchange methods configured, but " |
@@ -1961,13 +1804,6 @@ void QuicCryptoServerConfig::SetEphemeralKeySource( |
ephemeral_key_source_.reset(ephemeral_key_source); |
} |
-void QuicCryptoServerConfig::SetStrikeRegisterClient( |
- StrikeRegisterClient* strike_register_client) { |
- base::AutoLock locker(strike_register_client_lock_); |
- DCHECK(!strike_register_client_.get()); |
- strike_register_client_.reset(strike_register_client); |
-} |
- |
void QuicCryptoServerConfig::set_replay_protection(bool on) { |
replay_protection_ = on; |
} |
@@ -1976,26 +1812,6 @@ void QuicCryptoServerConfig::set_chlo_multiplier(size_t multiplier) { |
chlo_multiplier_ = multiplier; |
} |
-void QuicCryptoServerConfig::set_strike_register_no_startup_period() { |
- base::AutoLock locker(strike_register_client_lock_); |
- DCHECK(!strike_register_client_.get()); |
- strike_register_no_startup_period_ = true; |
-} |
- |
-void QuicCryptoServerConfig::set_strike_register_max_entries( |
- uint32_t max_entries) { |
- base::AutoLock locker(strike_register_client_lock_); |
- DCHECK(!strike_register_client_.get()); |
- strike_register_max_entries_ = max_entries; |
-} |
- |
-void QuicCryptoServerConfig::set_strike_register_window_secs( |
- uint32_t window_secs) { |
- base::AutoLock locker(strike_register_client_lock_); |
- DCHECK(!strike_register_client_.get()); |
- strike_register_window_secs_ = window_secs; |
-} |
- |
void QuicCryptoServerConfig::set_source_address_token_future_secs( |
uint32_t future_secs) { |
source_address_token_future_secs_ = future_secs; |
@@ -2006,18 +1822,6 @@ void QuicCryptoServerConfig::set_source_address_token_lifetime_secs( |
source_address_token_lifetime_secs_ = lifetime_secs; |
} |
-void QuicCryptoServerConfig::set_server_nonce_strike_register_max_entries( |
- uint32_t max_entries) { |
- DCHECK(!server_nonce_strike_register_.get()); |
- server_nonce_strike_register_max_entries_ = max_entries; |
-} |
- |
-void QuicCryptoServerConfig::set_server_nonce_strike_register_window_secs( |
- uint32_t window_secs) { |
- DCHECK(!server_nonce_strike_register_.get()); |
- server_nonce_strike_register_window_secs_ = window_secs; |
-} |
- |
void QuicCryptoServerConfig::set_enable_serving_sct(bool enable_serving_sct) { |
enable_serving_sct_ = enable_serving_sct; |
} |
@@ -2172,70 +1976,10 @@ string QuicCryptoServerConfig::NewServerNonce(QuicRandom* rand, |
StringPiece(reinterpret_cast<char*>(server_nonce), sizeof(server_nonce))); |
} |
-HandshakeFailureReason QuicCryptoServerConfig::ValidateServerNonce( |
- StringPiece token, |
- QuicWallTime now) const { |
- string storage; |
- StringPiece plaintext; |
- if (!server_nonce_boxer_.Unbox(token, &storage, &plaintext)) { |
- return SERVER_NONCE_DECRYPTION_FAILURE; |
- } |
- |
- // plaintext contains: |
- // uint32_t timestamp |
- // uint8_t[20] random bytes |
- |
- if (plaintext.size() != kServerNoncePlaintextSize) { |
- // This should never happen because the value decrypted correctly. |
- QUIC_BUG << "Seemingly valid server nonce had incorrect length."; |
- return SERVER_NONCE_INVALID_FAILURE; |
- } |
- |
- uint8_t server_nonce[32]; |
- memcpy(server_nonce, plaintext.data(), 4); |
- memcpy(server_nonce + 4, server_nonce_orbit_, sizeof(server_nonce_orbit_)); |
- memcpy(server_nonce + 4 + sizeof(server_nonce_orbit_), plaintext.data() + 4, |
- 20); |
- static_assert(4 + sizeof(server_nonce_orbit_) + 20 == sizeof(server_nonce), |
- "bad nonce buffer length"); |
- |
- InsertStatus nonce_error; |
- { |
- base::AutoLock auto_lock(server_nonce_strike_register_lock_); |
- if (server_nonce_strike_register_.get() == nullptr) { |
- server_nonce_strike_register_.reset(new StrikeRegister( |
- server_nonce_strike_register_max_entries_, |
- static_cast<uint32_t>(now.ToUNIXSeconds()), |
- server_nonce_strike_register_window_secs_, server_nonce_orbit_, |
- StrikeRegister::NO_STARTUP_PERIOD_NEEDED)); |
- } |
- nonce_error = server_nonce_strike_register_->Insert( |
- server_nonce, static_cast<uint32_t>(now.ToUNIXSeconds())); |
- } |
- |
- switch (nonce_error) { |
- case NONCE_OK: |
- return HANDSHAKE_OK; |
- case NONCE_INVALID_FAILURE: |
- case NONCE_INVALID_ORBIT_FAILURE: |
- return SERVER_NONCE_INVALID_FAILURE; |
- case NONCE_NOT_UNIQUE_FAILURE: |
- return SERVER_NONCE_NOT_UNIQUE_FAILURE; |
- case NONCE_INVALID_TIME_FAILURE: |
- return SERVER_NONCE_INVALID_TIME_FAILURE; |
- case NONCE_UNKNOWN_FAILURE: |
- case STRIKE_REGISTER_TIMEOUT: |
- case STRIKE_REGISTER_FAILURE: |
- default: |
- QUIC_BUG << "Unexpected server nonce error: " << nonce_error; |
- return SERVER_NONCE_NOT_UNIQUE_FAILURE; |
- } |
-} |
- |
bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( |
const CryptoHandshakeMessage& client_hello, |
- const QuicCryptoProof& crypto_proof) const { |
- if (crypto_proof.chain->certs.empty()) { |
+ const QuicSignedServerConfig& signed_config) const { |
+ if (signed_config.chain->certs.empty()) { |
return false; |
} |
@@ -2243,7 +1987,7 @@ bool QuicCryptoServerConfig::ValidateExpectedLeafCertificate( |
if (client_hello.GetUint64(kXLCT, &hash_from_client) != QUIC_NO_ERROR) { |
return false; |
} |
- return CryptoUtils::ComputeLeafCertHash(crypto_proof.chain->certs.at(0)) == |
+ return CryptoUtils::ComputeLeafCertHash(signed_config.chain->certs.at(0)) == |
hash_from_client; |
} |
@@ -2277,7 +2021,8 @@ QuicCryptoServerConfig::Config::Config() |
QuicCryptoServerConfig::Config::~Config() { |
} |
-QuicCryptoProof::QuicCryptoProof() {} |
-QuicCryptoProof::~QuicCryptoProof() {} |
+QuicSignedServerConfig::QuicSignedServerConfig() |
+ : send_expect_ct_header(false) {} |
+QuicSignedServerConfig::~QuicSignedServerConfig() {} |
} // namespace net |