| Index: net/quic/crypto/quic_crypto_server_config_test.cc
|
| diff --git a/net/quic/crypto/quic_crypto_server_config_test.cc b/net/quic/crypto/quic_crypto_server_config_test.cc
|
| deleted file mode 100644
|
| index 5134f505d402576b9095dea097e83f0bf2bde4b6..0000000000000000000000000000000000000000
|
| --- a/net/quic/crypto/quic_crypto_server_config_test.cc
|
| +++ /dev/null
|
| @@ -1,923 +0,0 @@
|
| -// Copyright 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/quic/crypto/quic_crypto_server_config.h"
|
| -
|
| -#include <stdarg.h>
|
| -
|
| -#include "base/stl_util.h"
|
| -#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
|
| -#include "net/quic/crypto/crypto_handshake_message.h"
|
| -#include "net/quic/crypto/crypto_secret_boxer.h"
|
| -#include "net/quic/crypto/crypto_server_config_protobuf.h"
|
| -#include "net/quic/crypto/quic_random.h"
|
| -#include "net/quic/crypto/strike_register_client.h"
|
| -#include "net/quic/quic_flags.h"
|
| -#include "net/quic/quic_time.h"
|
| -#include "net/quic/test_tools/mock_clock.h"
|
| -#include "net/quic/test_tools/quic_test_utils.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using base::StringPiece;
|
| -using std::map;
|
| -using std::pair;
|
| -using std::string;
|
| -using std::vector;
|
| -
|
| -namespace net {
|
| -namespace test {
|
| -
|
| -class QuicCryptoServerConfigPeer {
|
| - public:
|
| - explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
|
| - : server_config_(server_config) {}
|
| -
|
| - scoped_refptr<QuicCryptoServerConfig::Config> GetConfig(string config_id) {
|
| - base::AutoLock locked(server_config_->configs_lock_);
|
| - if (config_id == "<primary>") {
|
| - return scoped_refptr<QuicCryptoServerConfig::Config>(
|
| - server_config_->primary_config_);
|
| - } else {
|
| - return server_config_->GetConfigWithScid(config_id);
|
| - }
|
| - }
|
| -
|
| - bool ConfigHasDefaultSourceAddressTokenBoxer(string config_id) {
|
| - scoped_refptr<QuicCryptoServerConfig::Config> config = GetConfig(config_id);
|
| - return config->source_address_token_boxer ==
|
| - &(server_config_->default_source_address_token_boxer_);
|
| - }
|
| -
|
| - string NewSourceAddressToken(string config_id,
|
| - SourceAddressTokens previous_tokens,
|
| - const IPEndPoint& ip,
|
| - QuicRandom* rand,
|
| - QuicWallTime now,
|
| - CachedNetworkParameters* cached_network_params) {
|
| - return server_config_->NewSourceAddressToken(*GetConfig(config_id),
|
| - previous_tokens, ip, rand, now,
|
| - cached_network_params);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressToken(string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip,
|
| - QuicWallTime now) {
|
| - return ValidateSourceAddressToken(config_id, srct, ip, now, NULL);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressToken(
|
| - string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip,
|
| - QuicWallTime now,
|
| - CachedNetworkParameters* cached_network_params) {
|
| - return server_config_->ValidateSourceAddressToken(
|
| - *GetConfig(config_id), srct, ip, now, cached_network_params);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressTokens(string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip,
|
| - QuicWallTime now) {
|
| - return ValidateSourceAddressTokens(config_id, srct, ip, now, NULL);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressTokens(
|
| - string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip,
|
| - QuicWallTime now,
|
| - CachedNetworkParameters* cached_network_params) {
|
| - SourceAddressTokens tokens;
|
| - HandshakeFailureReason reason = server_config_->ParseSourceAddressToken(
|
| - *GetConfig(config_id), srct, &tokens);
|
| - if (reason != HANDSHAKE_OK) {
|
| - return reason;
|
| - }
|
| -
|
| - return server_config_->ValidateSourceAddressTokens(tokens, ip, now,
|
| - cached_network_params);
|
| - }
|
| -
|
| - string NewServerNonce(QuicRandom* rand, QuicWallTime now) const {
|
| - return server_config_->NewServerNonce(rand, now);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateServerNonce(StringPiece token,
|
| - QuicWallTime now) {
|
| - return server_config_->ValidateServerNonce(token, now);
|
| - }
|
| -
|
| - base::Lock* GetStrikeRegisterClientLock() {
|
| - return &server_config_->strike_register_client_lock_;
|
| - }
|
| -
|
| - // CheckConfigs compares the state of the Configs in |server_config_| to the
|
| - // description given as arguments. The arguments are given as
|
| - // nullptr-terminated pairs. The first of each pair is the server config ID of
|
| - // a Config. The second is a boolean describing whether the config is the
|
| - // primary. For example:
|
| - // CheckConfigs(nullptr); // checks that no Configs are loaded.
|
| - //
|
| - // // Checks that exactly three Configs are loaded with the given IDs and
|
| - // // status.
|
| - // CheckConfigs(
|
| - // "id1", false,
|
| - // "id2", true,
|
| - // "id3", false,
|
| - // nullptr);
|
| - void CheckConfigs(const char* server_config_id1, ...) {
|
| - va_list ap;
|
| - va_start(ap, server_config_id1);
|
| -
|
| - vector<pair<ServerConfigID, bool> > expected;
|
| - bool first = true;
|
| - for (;;) {
|
| - const char* server_config_id;
|
| - if (first) {
|
| - server_config_id = server_config_id1;
|
| - first = false;
|
| - } else {
|
| - server_config_id = va_arg(ap, const char*);
|
| - }
|
| -
|
| - if (!server_config_id) {
|
| - break;
|
| - }
|
| -
|
| - // varargs will promote the value to an int so we have to read that from
|
| - // the stack and cast down.
|
| - const bool is_primary = static_cast<bool>(va_arg(ap, int));
|
| - expected.push_back(std::make_pair(server_config_id, is_primary));
|
| - }
|
| -
|
| - va_end(ap);
|
| -
|
| - base::AutoLock locked(server_config_->configs_lock_);
|
| -
|
| - ASSERT_EQ(expected.size(), server_config_->configs_.size())
|
| - << ConfigsDebug();
|
| -
|
| - for (QuicCryptoServerConfig::ConfigMap::const_iterator
|
| - i = server_config_->configs_.begin();
|
| - i != server_config_->configs_.end(); ++i) {
|
| - bool found = false;
|
| - for (vector<pair<ServerConfigID, bool> >::iterator j = expected.begin();
|
| - j != expected.end(); ++j) {
|
| - if (i->first == j->first && i->second->is_primary == j->second) {
|
| - found = true;
|
| - j->first.clear();
|
| - break;
|
| - }
|
| - }
|
| -
|
| - ASSERT_TRUE(found) << "Failed to find match for " << i->first
|
| - << " in configs:\n" << ConfigsDebug();
|
| - }
|
| - }
|
| -
|
| - // ConfigsDebug returns a string that contains debugging information about
|
| - // the set of Configs loaded in |server_config_| and their status.
|
| - // ConfigsDebug() should be called after acquiring
|
| - // server_config_->configs_lock_.
|
| - string ConfigsDebug() {
|
| - if (server_config_->configs_.empty()) {
|
| - return "No Configs in QuicCryptoServerConfig";
|
| - }
|
| -
|
| - string s;
|
| -
|
| - for (QuicCryptoServerConfig::ConfigMap::const_iterator
|
| - i = server_config_->configs_.begin();
|
| - i != server_config_->configs_.end(); ++i) {
|
| - const scoped_refptr<QuicCryptoServerConfig::Config> config = i->second;
|
| - if (config->is_primary) {
|
| - s += "(primary) ";
|
| - } else {
|
| - s += " ";
|
| - }
|
| - s += config->id;
|
| - s += "\n";
|
| - }
|
| -
|
| - return s;
|
| - }
|
| -
|
| - void SelectNewPrimaryConfig(int seconds) {
|
| - base::AutoLock locked(server_config_->configs_lock_);
|
| - server_config_->SelectNewPrimaryConfig(
|
| - QuicWallTime::FromUNIXSeconds(seconds));
|
| - }
|
| -
|
| - private:
|
| - const QuicCryptoServerConfig* server_config_;
|
| -};
|
| -
|
| -class TestStrikeRegisterClient : public StrikeRegisterClient {
|
| - public:
|
| - explicit TestStrikeRegisterClient(QuicCryptoServerConfig* config)
|
| - : config_(config),
|
| - is_known_orbit_called_(false) {
|
| - }
|
| -
|
| - bool IsKnownOrbit(StringPiece orbit) const override {
|
| - // Ensure that the strike register client lock is not held.
|
| - QuicCryptoServerConfigPeer peer(config_);
|
| - base::Lock* m = peer.GetStrikeRegisterClientLock();
|
| - // In Chromium, we will dead lock if the lock is held by the current thread.
|
| - // Chromium doesn't have AssertNotHeld API call.
|
| - // m->AssertNotHeld();
|
| - base::AutoLock lock(*m);
|
| -
|
| - is_known_orbit_called_ = true;
|
| - return true;
|
| - }
|
| -
|
| - void VerifyNonceIsValidAndUnique(StringPiece nonce,
|
| - QuicWallTime now,
|
| - ResultCallback* cb) override {
|
| - LOG(FATAL) << "Not implemented";
|
| - }
|
| -
|
| - bool is_known_orbit_called() { return is_known_orbit_called_; }
|
| -
|
| - private:
|
| - QuicCryptoServerConfig* config_;
|
| - mutable bool is_known_orbit_called_;
|
| -};
|
| -
|
| -TEST(QuicCryptoServerConfigTest, ServerConfig) {
|
| - QuicRandom* rand = QuicRandom::GetInstance();
|
| - QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
|
| - MockClock clock;
|
| -
|
| - scoped_ptr<CryptoHandshakeMessage>(
|
| - server.AddDefaultConfig(rand, &clock,
|
| - QuicCryptoServerConfig::ConfigOptions()));
|
| -}
|
| -
|
| -TEST(QuicCryptoServerConfigTest, GetOrbitIsCalledWithoutTheStrikeRegisterLock) {
|
| - QuicRandom* rand = QuicRandom::GetInstance();
|
| - QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
|
| - MockClock clock;
|
| -
|
| - TestStrikeRegisterClient* strike_register =
|
| - new TestStrikeRegisterClient(&server);
|
| - server.SetStrikeRegisterClient(strike_register);
|
| -
|
| - QuicCryptoServerConfig::ConfigOptions options;
|
| - scoped_ptr<CryptoHandshakeMessage>(
|
| - server.AddDefaultConfig(rand, &clock, options));
|
| - EXPECT_TRUE(strike_register->is_known_orbit_called());
|
| -}
|
| -
|
| -class SourceAddressTokenTest : public ::testing::Test {
|
| - public:
|
| - SourceAddressTokenTest()
|
| - : ip4_(IPEndPoint(Loopback4(), 1)),
|
| - ip4_dual_(ConvertIPv4NumberToIPv6Number(ip4_.address()), 1),
|
| - ip6_(IPEndPoint(Loopback6(), 2)),
|
| - original_time_(QuicWallTime::Zero()),
|
| - rand_(QuicRandom::GetInstance()),
|
| - server_(QuicCryptoServerConfig::TESTING, rand_),
|
| - peer_(&server_) {
|
| - // Advance the clock to some non-zero time.
|
| - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000000));
|
| - original_time_ = clock_.WallNow();
|
| -
|
| - primary_config_.reset(server_.AddDefaultConfig(
|
| - rand_, &clock_, QuicCryptoServerConfig::ConfigOptions()));
|
| -
|
| - // Add a config that overrides the default boxer.
|
| - QuicCryptoServerConfig::ConfigOptions options;
|
| - options.id = kOverride;
|
| - override_config_protobuf_.reset(
|
| - QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options));
|
| - override_config_protobuf_->set_source_address_token_secret_override(
|
| - "a secret key");
|
| - // Lower priority than the default config.
|
| - override_config_protobuf_->set_priority(1);
|
| - override_config_.reset(
|
| - server_.AddConfig(override_config_protobuf_.get(), original_time_));
|
| - }
|
| -
|
| - string NewSourceAddressToken(string config_id, const IPEndPoint& ip) {
|
| - return NewSourceAddressToken(config_id, ip, NULL);
|
| - }
|
| -
|
| - string NewSourceAddressToken(string config_id,
|
| - const IPEndPoint& ip,
|
| - const SourceAddressTokens& previous_tokens) {
|
| - return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
|
| - clock_.WallNow(), NULL);
|
| - }
|
| -
|
| - string NewSourceAddressToken(string config_id,
|
| - const IPEndPoint& ip,
|
| - CachedNetworkParameters* cached_network_params) {
|
| - SourceAddressTokens previous_tokens;
|
| - return peer_.NewSourceAddressToken(config_id, previous_tokens, ip, rand_,
|
| - clock_.WallNow(), cached_network_params);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressToken(string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip) {
|
| - return ValidateSourceAddressToken(config_id, srct, ip, NULL);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressToken(
|
| - string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip,
|
| - CachedNetworkParameters* cached_network_params) {
|
| - return peer_.ValidateSourceAddressToken(
|
| - config_id, srct, ip, clock_.WallNow(), cached_network_params);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressTokens(string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip) {
|
| - return ValidateSourceAddressTokens(config_id, srct, ip, NULL);
|
| - }
|
| -
|
| - HandshakeFailureReason ValidateSourceAddressTokens(
|
| - string config_id,
|
| - StringPiece srct,
|
| - const IPEndPoint& ip,
|
| - CachedNetworkParameters* cached_network_params) {
|
| - return peer_.ValidateSourceAddressTokens(
|
| - config_id, srct, ip, clock_.WallNow(), cached_network_params);
|
| - }
|
| -
|
| - const string kPrimary = "<primary>";
|
| - const string kOverride = "Config with custom source address token key";
|
| -
|
| - IPEndPoint ip4_;
|
| - IPEndPoint ip4_dual_;
|
| - IPEndPoint ip6_;
|
| -
|
| - MockClock clock_;
|
| - QuicWallTime original_time_;
|
| - QuicRandom* rand_ = QuicRandom::GetInstance();
|
| - QuicCryptoServerConfig server_;
|
| - QuicCryptoServerConfigPeer peer_;
|
| - // Stores the primary config.
|
| - scoped_ptr<CryptoHandshakeMessage> primary_config_;
|
| - scoped_ptr<QuicServerConfigProtobuf> override_config_protobuf_;
|
| - scoped_ptr<CryptoHandshakeMessage> override_config_;
|
| -};
|
| -
|
| -TEST_F(SourceAddressTokenTest, SourceAddressToken) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - false);
|
| -
|
| - EXPECT_TRUE(peer_.ConfigHasDefaultSourceAddressTokenBoxer(kPrimary));
|
| - EXPECT_FALSE(peer_.ConfigHasDefaultSourceAddressTokenBoxer(kOverride));
|
| -
|
| - // Primary config generates configs that validate successfully.
|
| - const string token4 = NewSourceAddressToken(kPrimary, ip4_);
|
| - const string token4d = NewSourceAddressToken(kPrimary, ip4_dual_);
|
| - const string token6 = NewSourceAddressToken(kPrimary, ip6_);
|
| - EXPECT_EQ(HANDSHAKE_OK, ValidateSourceAddressToken(kPrimary, token4, ip4_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressToken(kPrimary, token4, ip4_dual_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
|
| - ValidateSourceAddressToken(kPrimary, token4, ip6_));
|
| - ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressToken(kPrimary, token4d, ip4_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressToken(kPrimary, token4d, ip4_dual_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
|
| - ValidateSourceAddressToken(kPrimary, token4d, ip6_));
|
| - ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressToken(kPrimary, token6, ip6_));
|
| -
|
| - // Override config generates configs that validate successfully.
|
| - const string override_token4 = NewSourceAddressToken(kOverride, ip4_);
|
| - const string override_token6 = NewSourceAddressToken(kOverride, ip6_);
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressToken(kOverride, override_token4, ip4_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
|
| - ValidateSourceAddressToken(kOverride, override_token4, ip6_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressToken(kOverride, override_token6, ip6_));
|
| -
|
| - // Tokens generated by the primary config do not validate
|
| - // successfully against the override config, and vice versa.
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressToken(kOverride, token4, ip4_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressToken(kOverride, token6, ip6_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressToken(kPrimary, override_token4, ip4_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressToken(kPrimary, override_token6, ip6_));
|
| -}
|
| -
|
| -TEST_F(SourceAddressTokenTest, SourceAddressTokenExpiration) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - false);
|
| -
|
| - const string token = NewSourceAddressToken(kPrimary, ip4_);
|
| -
|
| - // Validation fails if the token is from the future.
|
| - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(-3600 * 2));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
|
| - ValidateSourceAddressToken(kPrimary, token, ip4_));
|
| -
|
| - // Validation fails after tokens expire.
|
| - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400 * 7));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
|
| - ValidateSourceAddressToken(kPrimary, token, ip4_));
|
| -}
|
| -
|
| -TEST_F(SourceAddressTokenTest, SourceAddressTokenWithNetworkParams) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - false);
|
| -
|
| - // Make sure that if the source address token contains CachedNetworkParameters
|
| - // that this gets written to ValidateSourceAddressToken output argument.
|
| - CachedNetworkParameters cached_network_params_input;
|
| - cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
|
| - const string token4_with_cached_network_params =
|
| - NewSourceAddressToken(kPrimary, ip4_, &cached_network_params_input);
|
| -
|
| - CachedNetworkParameters cached_network_params_output;
|
| -#if 0
|
| - // TODO(rtenneti): For server, enable the following check after serialization
|
| - // of optional CachedNetworkParameters is implemented.
|
| - EXPECT_NE(cached_network_params_output.DebugString(),
|
| - cached_network_params_input.DebugString());
|
| -#endif
|
| - ValidateSourceAddressToken(kPrimary, token4_with_cached_network_params, ip4_,
|
| - &cached_network_params_output);
|
| -#if 0
|
| - // TODO(rtenneti): For server, enable the following check after serialization
|
| - // of optional CachedNetworkParameters is implemented.
|
| - EXPECT_EQ(cached_network_params_output.DebugString(),
|
| - cached_network_params_input.DebugString());
|
| -#endif
|
| -}
|
| -
|
| -// Test basic behavior of source address tokens including being specific
|
| -// to a single IP address and server config.
|
| -//
|
| -// TODO(rtenneti): For server, enable the following test after serialization of
|
| -// SourceAddressTokens is implemented.
|
| -TEST_F(SourceAddressTokenTest, DISABLED_NewSourceAddressToken) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - true);
|
| -
|
| - // Primary config generates configs that validate successfully.
|
| - const string token4 = NewSourceAddressToken(kPrimary, ip4_);
|
| - const string token4d = NewSourceAddressToken(kPrimary, ip4_dual_);
|
| - const string token6 = NewSourceAddressToken(kPrimary, ip6_);
|
| - EXPECT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4, ip4_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressTokens(kPrimary, token4, ip4_dual_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
|
| - ValidateSourceAddressTokens(kPrimary, token4, ip6_));
|
| - ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token4d, ip4_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressTokens(kPrimary, token4d, ip4_dual_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
|
| - ValidateSourceAddressTokens(kPrimary, token4d, ip6_));
|
| - ASSERT_EQ(HANDSHAKE_OK, ValidateSourceAddressTokens(kPrimary, token6, ip6_));
|
| -
|
| - // Override config generates configs that validate successfully.
|
| - const string override_token4 = NewSourceAddressToken(kOverride, ip4_);
|
| - const string override_token6 = NewSourceAddressToken(kOverride, ip6_);
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressTokens(kOverride, override_token4, ip4_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DIFFERENT_IP_ADDRESS_FAILURE,
|
| - ValidateSourceAddressTokens(kOverride, override_token4, ip6_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressTokens(kOverride, override_token6, ip6_));
|
| -
|
| - // Tokens generated by the primary config do not validate
|
| - // successfully against the override config, and vice versa.
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressTokens(kOverride, token4, ip4_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressTokens(kOverride, token6, ip6_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressTokens(kPrimary, override_token4, ip4_));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
|
| - ValidateSourceAddressTokens(kPrimary, override_token6, ip6_));
|
| -}
|
| -
|
| -// TODO(rtenneti): For server, enable the following test after serialization of
|
| -// SourceAddressTokens is implemented.
|
| -TEST_F(SourceAddressTokenTest, DISABLED_NewSourceAddressTokenExpiration) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - true);
|
| -
|
| - const string token = NewSourceAddressToken(kPrimary, ip4_);
|
| -
|
| - // Validation fails if the token is from the future.
|
| - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(-3600 * 2));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_CLOCK_SKEW_FAILURE,
|
| - ValidateSourceAddressTokens(kPrimary, token, ip4_));
|
| -
|
| - // Validation fails after tokens expire.
|
| - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(86400 * 7));
|
| - ASSERT_EQ(SOURCE_ADDRESS_TOKEN_EXPIRED_FAILURE,
|
| - ValidateSourceAddressTokens(kPrimary, token, ip4_));
|
| -}
|
| -
|
| -TEST_F(SourceAddressTokenTest, NewSourceAddressTokenWithNetworkParams) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - true);
|
| -
|
| - // Make sure that if the source address token contains CachedNetworkParameters
|
| - // that this gets written to ValidateSourceAddressToken output argument.
|
| - CachedNetworkParameters cached_network_params_input;
|
| - cached_network_params_input.set_bandwidth_estimate_bytes_per_second(1234);
|
| - const string token4_with_cached_network_params =
|
| - NewSourceAddressToken(kPrimary, ip4_, &cached_network_params_input);
|
| -
|
| - CachedNetworkParameters cached_network_params_output;
|
| -#if 0
|
| - // TODO(rtenneti): For server, enable the following check after serialization
|
| - // of optional CachedNetworkParameters is implemented.
|
| - EXPECT_NE(cached_network_params_output.DebugString(),
|
| - cached_network_params_input.DebugString());
|
| -#endif
|
| - ValidateSourceAddressTokens(kPrimary, token4_with_cached_network_params, ip4_,
|
| - &cached_network_params_output);
|
| -#if 0
|
| - // TODO(rtenneti): For server, enable the following check after serialization
|
| - // of optional CachedNetworkParameters is implemented.
|
| - EXPECT_EQ(cached_network_params_output.DebugString(),
|
| - cached_network_params_input.DebugString());
|
| -#endif
|
| -}
|
| -
|
| -// Test the ability for a source address token to be valid for multiple
|
| -// addresses.
|
| -//
|
| -// TODO(rtenneti): For server, enable the following test after serialization of
|
| -// SourceAddressTokens is implemented.
|
| -TEST_F(SourceAddressTokenTest, DISABLED_SourceAddressTokenMultipleAddresses) {
|
| - ValueRestore<bool> old_flag(&FLAGS_quic_use_multiple_address_in_source_tokens,
|
| - true);
|
| -
|
| - QuicWallTime now = clock_.WallNow();
|
| -
|
| - // Now create a token which is usable for both addresses.
|
| - SourceAddressToken previous_token;
|
| - IPAddressNumber ip_address = ip6_.address();
|
| - if (ip6_.GetSockAddrFamily() == AF_INET) {
|
| - ip_address = ConvertIPv4NumberToIPv6Number(ip_address);
|
| - }
|
| - previous_token.set_ip(IPAddressToPackedString(ip_address));
|
| - previous_token.set_timestamp(now.ToUNIXSeconds());
|
| - SourceAddressTokens previous_tokens;
|
| - (*previous_tokens.add_tokens()) = previous_token;
|
| - const string token4or6 =
|
| - NewSourceAddressToken(kPrimary, ip4_, previous_tokens);
|
| -
|
| - EXPECT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressTokens(kPrimary, token4or6, ip4_));
|
| - ASSERT_EQ(HANDSHAKE_OK,
|
| - ValidateSourceAddressTokens(kPrimary, token4or6, ip6_));
|
| -}
|
| -
|
| -TEST(QuicCryptoServerConfigTest, ValidateServerNonce) {
|
| - QuicRandom* rand = QuicRandom::GetInstance();
|
| - QuicCryptoServerConfig server(QuicCryptoServerConfig::TESTING, rand);
|
| - QuicCryptoServerConfigPeer peer(&server);
|
| -
|
| - StringPiece message("hello world");
|
| - const size_t key_size = CryptoSecretBoxer::GetKeySize();
|
| - scoped_ptr<uint8[]> key(new uint8[key_size]);
|
| - memset(key.get(), 0x11, key_size);
|
| -
|
| - CryptoSecretBoxer boxer;
|
| - boxer.SetKey(StringPiece(reinterpret_cast<char*>(key.get()), key_size));
|
| - const string box = boxer.Box(rand, message);
|
| - MockClock clock;
|
| - QuicWallTime now = clock.WallNow();
|
| - const QuicWallTime original_time = now;
|
| - EXPECT_EQ(SERVER_NONCE_DECRYPTION_FAILURE,
|
| - peer.ValidateServerNonce(box, now));
|
| -
|
| - string server_nonce = peer.NewServerNonce(rand, now);
|
| - EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now));
|
| - EXPECT_EQ(SERVER_NONCE_NOT_UNIQUE_FAILURE,
|
| - peer.ValidateServerNonce(server_nonce, now));
|
| -
|
| - now = original_time.Add(QuicTime::Delta::FromSeconds(1000 * 7));
|
| - server_nonce = peer.NewServerNonce(rand, now);
|
| - EXPECT_EQ(HANDSHAKE_OK, peer.ValidateServerNonce(server_nonce, now));
|
| -}
|
| -
|
| -class CryptoServerConfigsTest : public ::testing::Test {
|
| - public:
|
| - CryptoServerConfigsTest()
|
| - : rand_(QuicRandom::GetInstance()),
|
| - config_(QuicCryptoServerConfig::TESTING, rand_),
|
| - test_peer_(&config_) {}
|
| -
|
| - void SetUp() override {
|
| - clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1000));
|
| - }
|
| -
|
| - // SetConfigs constructs suitable config protobufs and calls SetConfigs on
|
| - // |config_|. The arguments are given as nullptr-terminated pairs. The first
|
| - // of each pair is the server config ID of a Config. The second is the
|
| - // |primary_time| of that Config, given in epoch seconds. (Although note that,
|
| - // in these tests, time is set to 1000 seconds since the epoch.) For example:
|
| - // SetConfigs(nullptr); // calls |config_.SetConfigs| with no protobufs.
|
| - //
|
| - // // Calls |config_.SetConfigs| with two protobufs: one for a Config with
|
| - // // a |primary_time| of 900 and priority 1, and another with
|
| - // // a |primary_time| of 1000 and priority 2.
|
| -
|
| - // CheckConfigs(
|
| - // "id1", 900, 1,
|
| - // "id2", 1000, 2,
|
| - // nullptr);
|
| - //
|
| - // If the server config id starts with "INVALID" then the generated protobuf
|
| - // will be invalid.
|
| - void SetConfigs(const char* server_config_id1, ...) {
|
| - const char kOrbit[] = "12345678";
|
| -
|
| - va_list ap;
|
| - va_start(ap, server_config_id1);
|
| - bool has_invalid = false;
|
| - bool is_empty = true;
|
| -
|
| - vector<QuicServerConfigProtobuf*> protobufs;
|
| - bool first = true;
|
| - for (;;) {
|
| - const char* server_config_id;
|
| - if (first) {
|
| - server_config_id = server_config_id1;
|
| - first = false;
|
| - } else {
|
| - server_config_id = va_arg(ap, const char*);
|
| - }
|
| -
|
| - if (!server_config_id) {
|
| - break;
|
| - }
|
| -
|
| - is_empty = false;
|
| - int primary_time = va_arg(ap, int);
|
| - int priority = va_arg(ap, int);
|
| -
|
| - QuicCryptoServerConfig::ConfigOptions options;
|
| - options.id = server_config_id;
|
| - options.orbit = kOrbit;
|
| - QuicServerConfigProtobuf* protobuf(
|
| - QuicCryptoServerConfig::GenerateConfig(rand_, &clock_, options));
|
| - protobuf->set_primary_time(primary_time);
|
| - protobuf->set_priority(priority);
|
| - if (string(server_config_id).find("INVALID") == 0) {
|
| - protobuf->clear_key();
|
| - has_invalid = true;
|
| - }
|
| - protobufs.push_back(protobuf);
|
| - }
|
| -
|
| - ASSERT_EQ(!has_invalid && !is_empty,
|
| - config_.SetConfigs(protobufs, clock_.WallNow()));
|
| - STLDeleteElements(&protobufs);
|
| - }
|
| -
|
| - protected:
|
| - QuicRandom* const rand_;
|
| - MockClock clock_;
|
| - QuicCryptoServerConfig config_;
|
| - QuicCryptoServerConfigPeer test_peer_;
|
| -};
|
| -
|
| -TEST_F(CryptoServerConfigsTest, NoConfigs) {
|
| - test_peer_.CheckConfigs(nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, MakePrimaryFirst) {
|
| - // Make sure that "b" is primary even though "a" comes first.
|
| - SetConfigs("a", 1100, 1,
|
| - "b", 900, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, MakePrimarySecond) {
|
| - // Make sure that a remains primary after b is added.
|
| - SetConfigs("a", 900, 1,
|
| - "b", 1100, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, Delete) {
|
| - // Ensure that configs get deleted when removed.
|
| - SetConfigs("a", 800, 1,
|
| - "b", 900, 1,
|
| - "c", 1100, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - "c", false,
|
| - nullptr);
|
| - SetConfigs("b", 900, 1,
|
| - "c", 1100, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "b", true,
|
| - "c", false,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, DeletePrimary) {
|
| - // Ensure that deleting the primary config works.
|
| - SetConfigs("a", 800, 1,
|
| - "b", 900, 1,
|
| - "c", 1100, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - "c", false,
|
| - nullptr);
|
| - SetConfigs("a", 800, 1,
|
| - "c", 1100, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "c", false,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, FailIfDeletingAllConfigs) {
|
| - // Ensure that configs get deleted when removed.
|
| - SetConfigs("a", 800, 1,
|
| - "b", 900, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - nullptr);
|
| - SetConfigs(nullptr);
|
| - // Config change is rejected, still using old configs.
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, ChangePrimaryTime) {
|
| - // Check that updates to primary time get picked up.
|
| - SetConfigs("a", 400, 1,
|
| - "b", 800, 1,
|
| - "c", 1200, 1,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(500);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - "c", false,
|
| - nullptr);
|
| - SetConfigs("a", 1200, 1,
|
| - "b", 800, 1,
|
| - "c", 400, 1,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(500);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", false,
|
| - "c", true,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, AllConfigsInThePast) {
|
| - // Check that the most recent config is selected.
|
| - SetConfigs("a", 400, 1,
|
| - "b", 800, 1,
|
| - "c", 1200, 1,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(1500);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", false,
|
| - "c", true,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, AllConfigsInTheFuture) {
|
| - // Check that the first config is selected.
|
| - SetConfigs("a", 400, 1,
|
| - "b", 800, 1,
|
| - "c", 1200, 1,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(100);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - "c", false,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, SortByPriority) {
|
| - // Check that priority is used to decide on a primary config when
|
| - // configs have the same primary time.
|
| - SetConfigs("a", 900, 1,
|
| - "b", 900, 2,
|
| - "c", 900, 3,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - "c", false,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(800);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - "c", false,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(1000);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - "c", false,
|
| - nullptr);
|
| -
|
| - // Change priorities and expect sort order to change.
|
| - SetConfigs("a", 900, 2,
|
| - "b", 900, 1,
|
| - "c", 900, 0,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", false,
|
| - "c", true,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(800);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", false,
|
| - "c", true,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(1000);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", false,
|
| - "c", true,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, AdvancePrimary) {
|
| - // Check that a new primary config is enabled at the right time.
|
| - SetConfigs("a", 900, 1,
|
| - "b", 1100, 1,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(1000);
|
| - test_peer_.CheckConfigs(
|
| - "a", true,
|
| - "b", false,
|
| - nullptr);
|
| - test_peer_.SelectNewPrimaryConfig(1101);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - nullptr);
|
| -}
|
| -
|
| -TEST_F(CryptoServerConfigsTest, InvalidConfigs) {
|
| - // Ensure that invalid configs don't change anything.
|
| - SetConfigs("a", 800, 1,
|
| - "b", 900, 1,
|
| - "c", 1100, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - "c", false,
|
| - nullptr);
|
| - SetConfigs("a", 800, 1,
|
| - "c", 1100, 1,
|
| - "INVALID1", 1000, 1,
|
| - nullptr);
|
| - test_peer_.CheckConfigs(
|
| - "a", false,
|
| - "b", true,
|
| - "c", false,
|
| - nullptr);
|
| -}
|
| -
|
| -} // namespace test
|
| -} // namespace net
|
|
|