1// Copyright 2013 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 5#include "net/quic/crypto/quic_crypto_client_config.h" 6 7#include "net/quic/crypto/proof_verifier.h" 8#include "net/quic/quic_server_id.h" 9#include "net/quic/test_tools/mock_random.h" 10#include "net/quic/test_tools/quic_test_utils.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13using std::string; 14using std::vector; 15 16namespace net { 17namespace test { 18 19TEST(QuicCryptoClientConfigTest, CachedState_IsEmpty) { 20 QuicCryptoClientConfig::CachedState state; 21 EXPECT_TRUE(state.IsEmpty()); 22} 23 24TEST(QuicCryptoClientConfigTest, CachedState_IsComplete) { 25 QuicCryptoClientConfig::CachedState state; 26 EXPECT_FALSE(state.IsComplete(QuicWallTime::FromUNIXSeconds(0))); 27} 28 29TEST(QuicCryptoClientConfigTest, CachedState_GenerationCounter) { 30 QuicCryptoClientConfig::CachedState state; 31 EXPECT_EQ(0u, state.generation_counter()); 32 state.SetProofInvalid(); 33 EXPECT_EQ(1u, state.generation_counter()); 34} 35 36TEST(QuicCryptoClientConfigTest, CachedState_SetProofVerifyDetails) { 37 QuicCryptoClientConfig::CachedState state; 38 EXPECT_TRUE(state.proof_verify_details() == NULL); 39 ProofVerifyDetails* details = new ProofVerifyDetails; 40 state.SetProofVerifyDetails(details); 41 EXPECT_EQ(details, state.proof_verify_details()); 42} 43 44TEST(QuicCryptoClientConfigTest, CachedState_InitializeFrom) { 45 QuicCryptoClientConfig::CachedState state; 46 QuicCryptoClientConfig::CachedState other; 47 state.set_source_address_token("TOKEN"); 48 // TODO(rch): Populate other fields of |state|. 49 other.InitializeFrom(state); 50 EXPECT_EQ(state.server_config(), other.server_config()); 51 EXPECT_EQ(state.source_address_token(), other.source_address_token()); 52 EXPECT_EQ(state.certs(), other.certs()); 53 EXPECT_EQ(1u, other.generation_counter()); 54} 55 56TEST(QuicCryptoClientConfigTest, InchoateChlo) { 57 QuicCryptoClientConfig::CachedState state; 58 QuicCryptoClientConfig config; 59 QuicCryptoNegotiatedParameters params; 60 CryptoHandshakeMessage msg; 61 QuicServerId server_id("www.google.com", 80, false, PRIVACY_MODE_DISABLED); 62 config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, 63 ¶ms, &msg); 64 65 QuicTag cver; 66 EXPECT_EQ(QUIC_NO_ERROR, msg.GetUint32(kVER, &cver)); 67 EXPECT_EQ(QuicVersionToQuicTag(QuicVersionMax()), cver); 68} 69 70TEST(QuicCryptoClientConfigTest, PreferAesGcm) { 71 QuicCryptoClientConfig config; 72 config.SetDefaults(); 73 if (config.aead.size() > 1) 74 EXPECT_NE(kAESG, config.aead[0]); 75 config.PreferAesGcm(); 76 EXPECT_EQ(kAESG, config.aead[0]); 77} 78 79TEST(QuicCryptoClientConfigTest, InchoateChloSecure) { 80 QuicCryptoClientConfig::CachedState state; 81 QuicCryptoClientConfig config; 82 QuicCryptoNegotiatedParameters params; 83 CryptoHandshakeMessage msg; 84 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED); 85 config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, 86 ¶ms, &msg); 87 88 QuicTag pdmd; 89 EXPECT_EQ(QUIC_NO_ERROR, msg.GetUint32(kPDMD, &pdmd)); 90 EXPECT_EQ(kX509, pdmd); 91} 92 93TEST(QuicCryptoClientConfigTest, InchoateChloSecureNoEcdsa) { 94 QuicCryptoClientConfig::CachedState state; 95 QuicCryptoClientConfig config; 96 config.DisableEcdsa(); 97 QuicCryptoNegotiatedParameters params; 98 CryptoHandshakeMessage msg; 99 QuicServerId server_id("www.google.com", 443, true, PRIVACY_MODE_DISABLED); 100 config.FillInchoateClientHello(server_id, QuicVersionMax(), &state, 101 ¶ms, &msg); 102 103 QuicTag pdmd; 104 EXPECT_EQ(QUIC_NO_ERROR, msg.GetUint32(kPDMD, &pdmd)); 105 EXPECT_EQ(kX59R, pdmd); 106} 107 108TEST(QuicCryptoClientConfigTest, FillClientHello) { 109 QuicCryptoClientConfig::CachedState state; 110 QuicCryptoClientConfig config; 111 QuicCryptoNegotiatedParameters params; 112 QuicConnectionId kConnectionId = 1234; 113 string error_details; 114 MockRandom rand; 115 CryptoHandshakeMessage chlo; 116 QuicServerId server_id("www.google.com", 80, false, PRIVACY_MODE_DISABLED); 117 config.FillClientHello(server_id, 118 kConnectionId, 119 QuicVersionMax(), 120 &state, 121 QuicWallTime::Zero(), 122 &rand, 123 NULL, // channel_id_key 124 ¶ms, 125 &chlo, 126 &error_details); 127 128 // Verify that certain QuicTags have been set correctly in the CHLO. 129 QuicTag cver; 130 EXPECT_EQ(QUIC_NO_ERROR, chlo.GetUint32(kVER, &cver)); 131 EXPECT_EQ(QuicVersionToQuicTag(QuicVersionMax()), cver); 132} 133 134TEST(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) { 135 QuicVersionVector supported_versions = QuicSupportedVersions(); 136 if (supported_versions.size() == 1) { 137 // No downgrade attack is possible if the client only supports one version. 138 return; 139 } 140 QuicTagVector supported_version_tags; 141 for (size_t i = supported_versions.size(); i > 0; --i) { 142 supported_version_tags.push_back( 143 QuicVersionToQuicTag(supported_versions[i - 1])); 144 } 145 CryptoHandshakeMessage msg; 146 msg.set_tag(kSHLO); 147 msg.SetVector(kVER, supported_version_tags); 148 149 QuicCryptoClientConfig::CachedState cached; 150 QuicCryptoNegotiatedParameters out_params; 151 string error; 152 QuicCryptoClientConfig config; 153 EXPECT_EQ(QUIC_VERSION_NEGOTIATION_MISMATCH, 154 config.ProcessServerHello(msg, 0, supported_versions, 155 &cached, &out_params, &error)); 156 EXPECT_EQ("Downgrade attack detected", error); 157} 158 159TEST(QuicCryptoClientConfigTest, InitializeFrom) { 160 QuicCryptoClientConfig config; 161 QuicServerId canonical_server_id("www.google.com", 80, false, 162 PRIVACY_MODE_DISABLED); 163 QuicCryptoClientConfig::CachedState* state = 164 config.LookupOrCreate(canonical_server_id); 165 // TODO(rch): Populate other fields of |state|. 166 state->set_source_address_token("TOKEN"); 167 state->SetProofValid(); 168 169 QuicServerId other_server_id("mail.google.com", 80, false, 170 PRIVACY_MODE_DISABLED); 171 config.InitializeFrom(other_server_id, canonical_server_id, &config); 172 QuicCryptoClientConfig::CachedState* other = 173 config.LookupOrCreate(other_server_id); 174 175 EXPECT_EQ(state->server_config(), other->server_config()); 176 EXPECT_EQ(state->source_address_token(), other->source_address_token()); 177 EXPECT_EQ(state->certs(), other->certs()); 178 EXPECT_EQ(1u, other->generation_counter()); 179} 180 181TEST(QuicCryptoClientConfigTest, Canonical) { 182 QuicCryptoClientConfig config; 183 config.AddCanonicalSuffix(".google.com"); 184 QuicServerId canonical_id1("www.google.com", 80, false, 185 PRIVACY_MODE_DISABLED); 186 QuicServerId canonical_id2("mail.google.com", 80, false, 187 PRIVACY_MODE_DISABLED); 188 QuicCryptoClientConfig::CachedState* state = 189 config.LookupOrCreate(canonical_id1); 190 // TODO(rch): Populate other fields of |state|. 191 state->set_source_address_token("TOKEN"); 192 state->SetProofValid(); 193 194 QuicCryptoClientConfig::CachedState* other = 195 config.LookupOrCreate(canonical_id2); 196 197 EXPECT_TRUE(state->IsEmpty()); 198 EXPECT_EQ(state->server_config(), other->server_config()); 199 EXPECT_EQ(state->source_address_token(), other->source_address_token()); 200 EXPECT_EQ(state->certs(), other->certs()); 201 EXPECT_EQ(1u, other->generation_counter()); 202 203 QuicServerId different_id("mail.google.org", 80, false, 204 PRIVACY_MODE_DISABLED); 205 EXPECT_TRUE(config.LookupOrCreate(different_id)->IsEmpty()); 206} 207 208TEST(QuicCryptoClientConfigTest, CanonicalNotUsedIfNotValid) { 209 QuicCryptoClientConfig config; 210 config.AddCanonicalSuffix(".google.com"); 211 QuicServerId canonical_id1("www.google.com", 80, false, 212 PRIVACY_MODE_DISABLED); 213 QuicServerId canonical_id2("mail.google.com", 80, false, 214 PRIVACY_MODE_DISABLED); 215 QuicCryptoClientConfig::CachedState* state = 216 config.LookupOrCreate(canonical_id1); 217 // TODO(rch): Populate other fields of |state|. 218 state->set_source_address_token("TOKEN"); 219 220 // Do not set the proof as valid, and check that it is not used 221 // as a canonical entry. 222 EXPECT_TRUE(config.LookupOrCreate(canonical_id2)->IsEmpty()); 223} 224 225TEST(QuicCryptoClientConfigTest, ClearCachedStates) { 226 QuicCryptoClientConfig config; 227 QuicServerId server_id("www.google.com", 80, false, PRIVACY_MODE_DISABLED); 228 QuicCryptoClientConfig::CachedState* state = config.LookupOrCreate(server_id); 229 // TODO(rch): Populate other fields of |state|. 230 vector<string> certs(1); 231 certs[0] = "Hello Cert"; 232 state->SetProof(certs, "signature"); 233 state->set_source_address_token("TOKEN"); 234 state->SetProofValid(); 235 EXPECT_EQ(1u, state->generation_counter()); 236 237 // Verify LookupOrCreate returns the same data. 238 QuicCryptoClientConfig::CachedState* other = config.LookupOrCreate(server_id); 239 240 EXPECT_EQ(state, other); 241 EXPECT_EQ(1u, other->generation_counter()); 242 243 // Clear the cached states. 244 config.ClearCachedStates(); 245 246 // Verify LookupOrCreate doesn't have any data. 247 QuicCryptoClientConfig::CachedState* cleared_cache = 248 config.LookupOrCreate(server_id); 249 250 EXPECT_EQ(state, cleared_cache); 251 EXPECT_FALSE(cleared_cache->proof_valid()); 252 EXPECT_TRUE(cleared_cache->server_config().empty()); 253 EXPECT_TRUE(cleared_cache->certs().empty()); 254 EXPECT_TRUE(cleared_cache->signature().empty()); 255 EXPECT_EQ(2u, cleared_cache->generation_counter()); 256} 257 258} // namespace test 259} // namespace net 260