Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Unified Diff: net/quic/crypto/quic_crypto_server_config.cc

Issue 213473003: This change introduces a way to tie source address token keys to specific QUIC server configs (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge internal change: 65382861 Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/quic/crypto/quic_crypto_server_config.cc
diff --git a/net/quic/crypto/quic_crypto_server_config.cc b/net/quic/crypto/quic_crypto_server_config.cc
index a6c099c875131b0a81c7f391571a451af46aa453..3b08ebad276b33211a3f025be3b7289776f40eab 100644
--- a/net/quic/crypto/quic_crypto_server_config.cc
+++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -46,6 +46,19 @@ using std::vector;
namespace net {
+namespace {
+
+string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) {
+ crypto::HKDF hkdf(source_address_token_secret,
+ StringPiece() /* no salt */,
+ "QUIC source address token key",
+ CryptoSecretBoxer::GetKeySize(),
+ 0 /* no fixed IV needed */);
+ return hkdf.server_write_key().as_string();
+}
+
+} // namespace
+
// ClientHelloInfo contains information about a client hello message that is
// only kept for as long as it's being processed.
struct ClientHelloInfo {
@@ -183,11 +196,8 @@ QuicCryptoServerConfig::QuicCryptoServerConfig(
source_address_token_lifetime_secs_(86400),
server_nonce_strike_register_max_entries_(1 << 10),
server_nonce_strike_register_window_secs_(120) {
- crypto::HKDF hkdf(source_address_token_secret, StringPiece() /* no salt */,
- "QUIC source address token key",
- CryptoSecretBoxer::GetKeySize(),
- 0 /* no fixed IV needed */);
- source_address_token_boxer_.SetKey(hkdf.server_write_key());
+ default_source_address_token_boxer_.SetKey(
+ DeriveSourceAddressTokenKey(source_address_token_secret));
// Generate a random key and orbit for server nonces.
rand->RandBytes(server_nonce_orbit_, sizeof(server_nonce_orbit_));
@@ -386,6 +396,7 @@ bool QuicCryptoServerConfig::SetConfigs(
parsed_configs.begin();
i != parsed_configs.end(); ++i) {
scoped_refptr<Config> config = *i;
+
ConfigMap::iterator it = configs_.find(config->id);
if (it != configs_.end()) {
VLOG(1)
@@ -440,7 +451,11 @@ void QuicCryptoServerConfig::ValidateClientHello(
new ValidateClientHelloResultCallback::Result(
client_hello, client_ip, now);
+ StringPiece requested_scid;
+ client_hello.GetStringPiece(kSCID, &requested_scid);
+
uint8 primary_orbit[kOrbitSize];
+ scoped_refptr<Config> requested_config;
{
base::AutoLock locked(configs_lock_);
@@ -457,10 +472,15 @@ void QuicCryptoServerConfig::ValidateClientHello(
memcpy(primary_orbit, primary_config_->orbit, sizeof(primary_orbit));
}
+
+ // We'll use the config that the client requested in order to do
+ // key-agreement. Otherwise we'll give it a copy of |primary_config_|
+ // to use.
wtc 2014/04/22 19:12:10 IMPORTANT: The original code doesn't have this com
ramant (doing other things) 2014/04/25 23:40:58 Done.
+ requested_config = GetConfigWithScid(requested_scid);
}
if (result->error_code == QUIC_NO_ERROR) {
- EvaluateClientHello(primary_orbit, result, done_cb);
+ EvaluateClientHello(primary_orbit, requested_config, result, done_cb);
} else {
done_cb->Run(result);
}
@@ -527,17 +547,12 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
DCHECK(configs_.find(primary_config_->id)->second == primary_config_);
}
+ // We'll use the config that the client requested in order to do
+ // key-agreement. Otherwise we'll give it a copy of |primary_config_|
+ // to use.
primary_config = primary_config_;
- if (!requested_scid.empty()) {
- ConfigMap::const_iterator it = configs_.find(requested_scid.as_string());
- if (it != configs_.end()) {
- // We'll use the config that the client requested in order to do
- // key-agreement. Otherwise we'll give it a copy of |primary_config_|
- // to use.
- requested_config = it->second;
- }
- }
+ requested_config = GetConfigWithScid(requested_scid);
}
if (validate_chlo_result.error_code != QUIC_NO_ERROR) {
@@ -551,7 +566,7 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
!info.client_nonce_well_formed ||
!info.unique ||
!requested_config.get()) {
- BuildRejection(primary_config.get(), client_hello, info, rand, out);
+ BuildRejection(*primary_config, client_hello, info, rand, out);
return QUIC_NO_ERROR;
}
@@ -718,7 +733,10 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
}
out->SetVector(kVER, supported_version_tags);
out->SetStringPiece(kSourceAddressTokenTag,
- NewSourceAddressToken(client_address, rand, info.now));
+ NewSourceAddressToken(
+ *requested_config,
+ client_address, rand,
+ info.now));
QuicSocketAddressCoder address_coder(client_address);
out->SetStringPiece(kCADR, address_coder.Encode());
out->SetStringPiece(kPUBS, forward_secure_public_value);
@@ -729,6 +747,24 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
return QUIC_NO_ERROR;
}
+scoped_refptr<QuicCryptoServerConfig::Config>
wtc 2014/04/22 19:12:10 Please see if we can change QuicCryptoServerConfig
ramant (doing other things) 2014/04/25 23:40:58 Wasn't able to. Compile errors on linux. ../../ne
+QuicCryptoServerConfig::GetConfigWithScid(StringPiece requested_scid) const {
+ // In Chromium, we will dead lock if the lock is held by the current thread.
+ // Chromium doesn't have AssertReaderHeld API call.
+ // configs_lock_.AssertReaderHeld();
+
+ if (!requested_scid.empty()) {
+ ConfigMap::const_iterator it = configs_.find(requested_scid.as_string());
+ if (it != configs_.end()) {
+ // We'll use the config that the client requested in order to do
+ // key-agreement.
+ return scoped_refptr<Config>(it->second);
+ }
+ }
+
+ return scoped_refptr<Config>();
+}
+
// ConfigPrimaryTimeLessThan is a comparator that implements "less than" for
// Config's based on their primary_time.
// static
@@ -823,7 +859,9 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig(
DVLOG(1) << "New primary config. orbit: "
<< base::HexEncode(
reinterpret_cast<const char*>(primary_config_->orbit),
- kOrbitSize);
+ kOrbitSize)
+ << " scid: " << base::HexEncode(primary_config_->id.data(),
+ primary_config_->id.size());
next_config_promotion_time_ = QuicWallTime::Zero();
if (primary_config_changed_cb_.get() != NULL) {
primary_config_changed_cb_->Run(primary_config_->id);
@@ -832,6 +870,7 @@ void QuicCryptoServerConfig::SelectNewPrimaryConfig(
void QuicCryptoServerConfig::EvaluateClientHello(
const uint8* primary_orbit,
+ scoped_refptr<Config> requested_config,
ValidateClientHelloResultCallback::Result* client_hello_state,
ValidateClientHelloResultCallback* done_cb) const {
ValidateClientHelloHelper helper(client_hello_state, done_cb);
@@ -854,11 +893,15 @@ void QuicCryptoServerConfig::EvaluateClientHello(
}
StringPiece srct;
- if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) &&
- ValidateSourceAddressToken(srct, info->client_ip, info->now)) {
+ if (requested_config.get() != NULL &&
+ client_hello.GetStringPiece(kSourceAddressTokenTag, &srct) &&
+ ValidateSourceAddressToken(*requested_config,
+ srct,
+ info->client_ip,
+ info->now)) {
info->valid_source_address_token = true;
} else {
- // No valid source address token.
+ // No server config with the requested ID, or no valid source address token.
helper.ValidationComplete(QUIC_NO_ERROR, "");
return;
}
@@ -915,15 +958,19 @@ void QuicCryptoServerConfig::EvaluateClientHello(
}
void QuicCryptoServerConfig::BuildRejection(
- const scoped_refptr<Config>& config,
+ const Config& config,
const CryptoHandshakeMessage& client_hello,
const ClientHelloInfo& info,
QuicRandom* rand,
CryptoHandshakeMessage* out) const {
out->set_tag(kREJ);
- out->SetStringPiece(kSCFG, config->serialized);
+ out->SetStringPiece(kSCFG, config.serialized);
out->SetStringPiece(kSourceAddressTokenTag,
- NewSourceAddressToken(info.client_ip, rand, info.now));
+ NewSourceAddressToken(
+ config,
+ info.client_ip,
+ rand,
+ info.now));
if (replay_protection_) {
out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now));
}
@@ -958,7 +1005,7 @@ void QuicCryptoServerConfig::BuildRejection(
const vector<string>* certs;
string signature;
- if (!proof_source_->GetProof(info.sni.as_string(), config->serialized,
+ if (!proof_source_->GetProof(info.sni.as_string(), config.serialized,
x509_ecdsa_supported, &certs, &signature)) {
return;
}
@@ -970,7 +1017,7 @@ void QuicCryptoServerConfig::BuildRejection(
const string compressed = CertCompressor::CompressChain(
*certs, their_common_set_hashes, their_cached_cert_hashes,
- config->common_cert_sets);
+ config.common_cert_sets);
// kREJOverheadBytes is a very rough estimate of how much of a REJ
// message is taken up by things other than the certificates.
@@ -1013,6 +1060,18 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
scoped_refptr<Config> config(new Config);
config->serialized = protobuf->config();
+ if (!protobuf->has_source_address_token_secret_override()) {
+ // Use the default boxer.
+ config->source_address_token_boxer = &default_source_address_token_boxer_;
+ } else {
+ // Create override boxer instance.
+ CryptoSecretBoxer* boxer = new CryptoSecretBoxer;
+ boxer->SetKey(DeriveSourceAddressTokenKey(
+ protobuf->source_address_token_secret_override()));
+ config->source_address_token_boxer_storage.reset(boxer);
+ config->source_address_token_boxer = boxer;
+ }
+
if (protobuf->has_primary_time()) {
config->primary_time =
QuicWallTime::FromUNIXSeconds(protobuf->primary_time());
@@ -1044,7 +1103,7 @@ QuicCryptoServerConfig::ParseConfigProtobuf(
StringPiece orbit;
if (!msg->GetStringPiece(kORBT, &orbit)) {
- LOG(WARNING) << "Server config message is missing OBIT";
+ LOG(WARNING) << "Server config message is missing ORBT";
return NULL;
}
@@ -1218,6 +1277,7 @@ void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
}
string QuicCryptoServerConfig::NewSourceAddressToken(
+ const QuicCryptoServerConfig::Config& config,
const IPEndPoint& ip,
QuicRandom* rand,
QuicWallTime now) const {
@@ -1225,17 +1285,18 @@ string QuicCryptoServerConfig::NewSourceAddressToken(
source_address_token.set_ip(IPAddressToPackedString(ip.address()));
source_address_token.set_timestamp(now.ToUNIXSeconds());
- return source_address_token_boxer_.Box(
+ return config.source_address_token_boxer->Box(
rand, source_address_token.SerializeAsString());
}
bool QuicCryptoServerConfig::ValidateSourceAddressToken(
+ const QuicCryptoServerConfig::Config& config,
wtc 2014/04/22 19:12:10 Change QuicCryptoServerConfig::Config to Config on
ramant (doing other things) 2014/04/25 23:40:58 Done.
StringPiece token,
const IPEndPoint& ip,
QuicWallTime now) const {
string storage;
StringPiece plaintext;
- if (!source_address_token_boxer_.Unbox(token, &storage, &plaintext)) {
+ if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
return false;
}
@@ -1337,7 +1398,8 @@ QuicCryptoServerConfig::Config::Config()
: channel_id_enabled(false),
is_primary(false),
primary_time(QuicWallTime::Zero()),
- priority(0) {}
+ priority(0),
+ source_address_token_boxer(NULL) {}
QuicCryptoServerConfig::Config::~Config() { STLDeleteElements(&key_exchanges); }

Powered by Google App Engine
This is Rietveld 408576698