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                                 &params, &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                                 &params, &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                                 &params, &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                         &params,
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