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

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

Issue 822713002: Update from https://crrev.com/309415 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 6 years 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 f752a9e6a0aae60e5e54839eec7b0eb3f8bd0172..4a5dc8a75806da293e0f8948080064d720228354 100644
--- a/net/quic/crypto/quic_crypto_server_config.cc
+++ b/net/quic/crypto/quic_crypto_server_config.cc
@@ -50,6 +50,8 @@ namespace net {
namespace {
+const size_t kMaxTokenAddresses = 4;
+
string DeriveSourceAddressTokenKey(StringPiece source_address_token_secret) {
crypto::HKDF hkdf(source_address_token_secret,
StringPiece() /* no salt */,
@@ -765,12 +767,10 @@ QuicErrorCode QuicCryptoServerConfig::ProcessClientHello(
(QuicVersionToQuicTag(supported_versions[i]));
}
out->SetVector(kVER, supported_version_tags);
- out->SetStringPiece(kSourceAddressTokenTag,
- NewSourceAddressToken(*requested_config.get(),
- client_address,
- rand,
- info.now,
- nullptr));
+ out->SetStringPiece(
+ kSourceAddressTokenTag,
+ NewSourceAddressToken(*requested_config.get(), info.source_address_tokens,
+ client_address, rand, info.now, nullptr));
QuicSocketAddressCoder address_coder(client_address);
out->SetStringPiece(kCADR, address_coder.Encode());
out->SetStringPiece(kPUBS, forward_secure_public_value);
@@ -940,12 +940,20 @@ void QuicCryptoServerConfig::EvaluateClientHello(
HandshakeFailureReason source_address_token_error;
StringPiece srct;
if (client_hello.GetStringPiece(kSourceAddressTokenTag, &srct)) {
- source_address_token_error =
- ValidateSourceAddressToken(*requested_config.get(),
- srct,
- info->client_ip,
- info->now,
- &client_hello_state->cached_network_params);
+ if (!FLAGS_quic_use_multiple_address_in_source_tokens) {
+ source_address_token_error = ValidateSourceAddressToken(
+ *requested_config.get(), srct, info->client_ip, info->now,
+ &client_hello_state->cached_network_params);
+ } else {
+ source_address_token_error = ParseSourceAddressToken(
+ *requested_config.get(), srct, &info->source_address_tokens);
+
+ if (source_address_token_error == HANDSHAKE_OK) {
+ source_address_token_error = ValidateSourceAddressTokens(
+ info->source_address_tokens, info->client_ip, info->now,
+ &client_hello_state->cached_network_params);
+ }
+ }
info->valid_source_address_token =
(source_address_token_error == HANDSHAKE_OK);
} else {
@@ -1035,6 +1043,7 @@ void QuicCryptoServerConfig::EvaluateClientHello(
}
bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
+ const SourceAddressTokens& previous_source_address_tokens,
const IPEndPoint& server_ip,
const IPEndPoint& client_ip,
const QuicClock* clock,
@@ -1045,12 +1054,11 @@ bool QuicCryptoServerConfig::BuildServerConfigUpdateMessage(
base::AutoLock locked(configs_lock_);
out->set_tag(kSCUP);
out->SetStringPiece(kSCFG, primary_config_->serialized);
- out->SetStringPiece(kSourceAddressTokenTag,
- NewSourceAddressToken(*primary_config_.get(),
- client_ip,
- rand,
- clock->WallNow(),
- cached_network_params));
+ out->SetStringPiece(
+ kSourceAddressTokenTag,
+ NewSourceAddressToken(*primary_config_.get(),
+ previous_source_address_tokens, client_ip, rand,
+ clock->WallNow(), cached_network_params));
if (proof_source_ == nullptr) {
// Insecure QUIC, can send SCFG without proof.
@@ -1086,13 +1094,10 @@ void QuicCryptoServerConfig::BuildRejection(
CryptoHandshakeMessage* out) const {
out->set_tag(kREJ);
out->SetStringPiece(kSCFG, config.serialized);
- out->SetStringPiece(kSourceAddressTokenTag,
- NewSourceAddressToken(
- config,
- info.client_ip,
- rand,
- info.now,
- &cached_network_params));
+ out->SetStringPiece(
+ kSourceAddressTokenTag,
+ NewSourceAddressToken(config, info.source_address_tokens, info.client_ip,
+ rand, info.now, &cached_network_params));
if (replay_protection_) {
out->SetStringPiece(kServerNonceTag, NewServerNonce(rand, info.now));
}
@@ -1412,6 +1417,7 @@ void QuicCryptoServerConfig::AcquirePrimaryConfigChangedCb(
string QuicCryptoServerConfig::NewSourceAddressToken(
const Config& config,
+ const SourceAddressTokens& previous_tokens,
const IPEndPoint& ip,
QuicRandom* rand,
QuicWallTime now,
@@ -1420,21 +1426,80 @@ string QuicCryptoServerConfig::NewSourceAddressToken(
if (ip.GetSockAddrFamily() == AF_INET) {
ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
}
- SourceAddressToken source_address_token;
- source_address_token.set_ip(IPAddressToPackedString(ip_address));
- source_address_token.set_timestamp(now.ToUNIXSeconds());
+ SourceAddressTokens source_address_tokens;
+ SourceAddressToken* source_address_token = source_address_tokens.add_tokens();
+ source_address_token->set_ip(IPAddressToPackedString(ip_address));
+ source_address_token->set_timestamp(now.ToUNIXSeconds());
if (cached_network_params != nullptr) {
- source_address_token.set_cached_network_parameters(*cached_network_params);
+ *(source_address_token->mutable_cached_network_parameters()) =
+ *cached_network_params;
+ }
+
+ if (!FLAGS_quic_use_multiple_address_in_source_tokens) {
+ return config.source_address_token_boxer->Box(
+ rand, source_address_token->SerializeAsString());
+ }
+
+ // Append previous tokens.
+ for (size_t i = 0; i < previous_tokens.tokens_size(); i++) {
+ const SourceAddressToken& token = previous_tokens.tokens(i);
+ if (source_address_tokens.tokens_size() > kMaxTokenAddresses) {
+ break;
+ }
+
+ if (token.ip() == source_address_token->ip()) {
+ // It's for the same IP address.
+ continue;
+ }
+
+ if (ValidateSourceAddressTokenTimestamp(token, now) != HANDSHAKE_OK) {
+ continue;
+ }
+
+ *(source_address_tokens.add_tokens()) = token;
}
return config.source_address_token_boxer->Box(
- rand, source_address_token.SerializeAsString());
+ rand, source_address_tokens.SerializeAsString());
}
bool QuicCryptoServerConfig::HasProofSource() const {
return proof_source_ != nullptr;
}
+HandshakeFailureReason QuicCryptoServerConfig::ParseSourceAddressToken(
+ const Config& config,
+ StringPiece token,
+ SourceAddressTokens* tokens) const {
+ string storage;
+ StringPiece plaintext;
+ if (!config.source_address_token_boxer->Unbox(token, &storage, &plaintext)) {
+ return SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE;
+ }
+
+ if (!FLAGS_quic_use_multiple_address_in_source_tokens) {
+ SourceAddressToken token;
+ if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
+ return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
+ }
+ *(tokens->add_tokens()) = token;
+ return HANDSHAKE_OK;
+ }
+
+ if (!tokens->ParseFromArray(plaintext.data(), plaintext.size())) {
+ // Some clients might still be using the old source token format so
+ // attempt to parse that format.
+ // TODO(rch): remove this code once the new format is ubiquitous.
+ SourceAddressToken token;
+ if (!token.ParseFromArray(plaintext.data(), plaintext.size())) {
+ return SOURCE_ADDRESS_TOKEN_PARSE_FAILURE;
+ }
+ *tokens->add_tokens() = token;
+ }
+
+ return HANDSHAKE_OK;
+}
+
HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken(
const Config& config,
StringPiece token,
@@ -1483,6 +1548,63 @@ HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressToken(
return HANDSHAKE_OK;
}
+HandshakeFailureReason QuicCryptoServerConfig::ValidateSourceAddressTokens(
+ const SourceAddressTokens& source_address_tokens,
+ const IPEndPoint& ip,
+ QuicWallTime now,
+ CachedNetworkParameters* cached_network_params) const {
+ HandshakeFailureReason reason =
+ SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
+ for (size_t i = 0; i < source_address_tokens.tokens_size(); i++) {
+ const SourceAddressToken& token = source_address_tokens.tokens(i);
+ reason = ValidateSingleSourceAddressToken(token, ip, now);
+ if (reason == HANDSHAKE_OK) {
+ if (token.has_cached_network_parameters()) {
+ *cached_network_params = token.cached_network_parameters();
+ }
+ break;
+ }
+ }
+ return reason;
+}
+
+HandshakeFailureReason QuicCryptoServerConfig::ValidateSingleSourceAddressToken(
+ const SourceAddressToken& source_address_token,
+ const IPEndPoint& ip,
+ QuicWallTime now) const {
+ IPAddressNumber ip_address = ip.address();
+ if (ip.GetSockAddrFamily() == AF_INET) {
+ ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
+ }
+ if (source_address_token.ip() != IPAddressToPackedString(ip_address)) {
+ // It's for a different IP address.
+ return SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE;
+ }
+
+ return ValidateSourceAddressTokenTimestamp(source_address_token, now);
+}
+
+HandshakeFailureReason
+QuicCryptoServerConfig::ValidateSourceAddressTokenTimestamp(
+ const SourceAddressToken& source_address_token,
+ QuicWallTime now) const {
+ const QuicWallTime timestamp(
+ QuicWallTime::FromUNIXSeconds(source_address_token.timestamp()));
+ const QuicTime::Delta delta(now.AbsoluteDifference(timestamp));
+
+ if (now.IsBefore(timestamp) &&
+ delta.ToSeconds() > source_address_token_future_secs_) {
+ return SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE;
+ }
+
+ if (now.IsAfter(timestamp) &&
+ delta.ToSeconds() > source_address_token_lifetime_secs_) {
+ return SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE;
+ }
+
+ return HANDSHAKE_OK;
+}
+
// kServerNoncePlaintextSize is the number of bytes in an unencrypted server
// nonce.
static const size_t kServerNoncePlaintextSize =

Powered by Google App Engine
This is Rietveld 408576698