| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/strings/string_number_conversions.h" | 6 #include "base/strings/string_number_conversions.h" |
| 7 #include "crypto/secure_hash.h" | 7 #include "crypto/secure_hash.h" |
| 8 #include "net/quic/crypto/crypto_utils.h" | 8 #include "net/quic/crypto/crypto_utils.h" |
| 9 #include "net/quic/crypto/quic_crypto_server_config.h" | 9 #include "net/quic/crypto/quic_crypto_server_config.h" |
| 10 #include "net/quic/crypto/quic_random.h" | 10 #include "net/quic/crypto/quic_random.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 client_address_(Loopback4(), 1234), | 43 client_address_(Loopback4(), 1234), |
| 44 config_(QuicCryptoServerConfig::TESTING, rand_) { | 44 config_(QuicCryptoServerConfig::TESTING, rand_) { |
| 45 config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting()); | 45 config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting()); |
| 46 supported_versions_ = QuicSupportedVersions(); | 46 supported_versions_ = QuicSupportedVersions(); |
| 47 client_version_ = QuicUtils::TagToString( | 47 client_version_ = QuicUtils::TagToString( |
| 48 QuicVersionToQuicTag(supported_versions_.front())); | 48 QuicVersionToQuicTag(supported_versions_.front())); |
| 49 } | 49 } |
| 50 | 50 |
| 51 virtual void SetUp() { | 51 virtual void SetUp() { |
| 52 scoped_ptr<CryptoHandshakeMessage> msg( | 52 scoped_ptr<CryptoHandshakeMessage> msg( |
| 53 config_.AddDefaultConfig(rand_, &clock_, | 53 config_.AddDefaultConfig(rand_, &clock_, config_options_)); |
| 54 config_options_)); | |
| 55 | 54 |
| 56 StringPiece orbit; | 55 StringPiece orbit; |
| 57 CHECK(msg->GetStringPiece(kORBT, &orbit)); | 56 CHECK(msg->GetStringPiece(kORBT, &orbit)); |
| 58 CHECK_EQ(sizeof(orbit_), orbit.size()); | 57 CHECK_EQ(sizeof(orbit_), orbit.size()); |
| 59 memcpy(orbit_, orbit.data(), orbit.size()); | 58 memcpy(orbit_, orbit.data(), orbit.size()); |
| 60 | 59 |
| 61 char public_value[32]; | 60 char public_value[32]; |
| 62 memset(public_value, 42, sizeof(public_value)); | 61 memset(public_value, 42, sizeof(public_value)); |
| 63 | 62 |
| 64 const string nonce_str = GenerateNonce(); | 63 const string nonce_str = GenerateNonce(); |
| 65 nonce_hex_ = "#" + base::HexEncode(nonce_str.data(), nonce_str.size()); | 64 nonce_hex_ = "#" + base::HexEncode(nonce_str.data(), nonce_str.size()); |
| 66 pub_hex_ = "#" + base::HexEncode(public_value, sizeof(public_value)); | 65 pub_hex_ = "#" + base::HexEncode(public_value, sizeof(public_value)); |
| 67 | 66 |
| 68 CryptoHandshakeMessage client_hello = CryptoTestUtils::Message( | 67 CryptoHandshakeMessage client_hello = |
| 69 "CHLO", | 68 CryptoTestUtils::Message("CHLO", |
| 70 "AEAD", "AESG", | 69 "AEAD", |
| 71 "KEXS", "C255", | 70 "AESG", |
| 72 "PUBS", pub_hex_.c_str(), | 71 "KEXS", |
| 73 "NONC", nonce_hex_.c_str(), | 72 "C255", |
| 74 "VER\0", client_version_.data(), | 73 "PUBS", |
| 75 "$padding", static_cast<int>(kClientHelloMinimumSize), | 74 pub_hex_.c_str(), |
| 76 NULL); | 75 "NONC", |
| 76 nonce_hex_.c_str(), |
| 77 "VER\0", |
| 78 client_version_.data(), |
| 79 "$padding", |
| 80 static_cast<int>(kClientHelloMinimumSize), |
| 81 NULL); |
| 77 ShouldSucceed(client_hello); | 82 ShouldSucceed(client_hello); |
| 78 // The message should be rejected because the source-address token is | 83 // The message should be rejected because the source-address token is |
| 79 // missing. | 84 // missing. |
| 80 ASSERT_EQ(kREJ, out_.tag()); | 85 ASSERT_EQ(kREJ, out_.tag()); |
| 81 | 86 |
| 82 StringPiece srct; | 87 StringPiece srct; |
| 83 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); | 88 ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); |
| 84 srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size()); | 89 srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size()); |
| 85 | 90 |
| 86 StringPiece scfg; | 91 StringPiece scfg; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 EXPECT_EQ(client_address_.address(), decoder.ip()); | 152 EXPECT_EQ(client_address_.address(), decoder.ip()); |
| 148 EXPECT_EQ(client_address_.port(), decoder.port()); | 153 EXPECT_EQ(client_address_.port(), decoder.port()); |
| 149 } | 154 } |
| 150 | 155 |
| 151 void ShouldSucceed(const CryptoHandshakeMessage& message) { | 156 void ShouldSucceed(const CryptoHandshakeMessage& message) { |
| 152 bool called = false; | 157 bool called = false; |
| 153 RunValidate(message, new ValidateCallback(this, true, "", &called)); | 158 RunValidate(message, new ValidateCallback(this, true, "", &called)); |
| 154 EXPECT_TRUE(called); | 159 EXPECT_TRUE(called); |
| 155 } | 160 } |
| 156 | 161 |
| 157 void RunValidate( | 162 void RunValidate(const CryptoHandshakeMessage& message, |
| 158 const CryptoHandshakeMessage& message, | 163 ValidateClientHelloResultCallback* cb) { |
| 159 ValidateClientHelloResultCallback* cb) { | |
| 160 config_.ValidateClientHello(message, client_address_, &clock_, cb); | 164 config_.ValidateClientHello(message, client_address_, &clock_, cb); |
| 161 } | 165 } |
| 162 | 166 |
| 163 void ShouldFailMentioning(const char* error_substr, | 167 void ShouldFailMentioning(const char* error_substr, |
| 164 const CryptoHandshakeMessage& message) { | 168 const CryptoHandshakeMessage& message) { |
| 165 bool called = false; | 169 bool called = false; |
| 166 ShouldFailMentioning(error_substr, message, &called); | 170 ShouldFailMentioning(error_substr, message, &called); |
| 167 EXPECT_TRUE(called); | 171 EXPECT_TRUE(called); |
| 168 } | 172 } |
| 169 | 173 |
| 170 void ShouldFailMentioning(const char* error_substr, | 174 void ShouldFailMentioning(const char* error_substr, |
| 171 const CryptoHandshakeMessage& message, | 175 const CryptoHandshakeMessage& message, |
| 172 bool* called) { | 176 bool* called) { |
| 173 config_.ValidateClientHello( | 177 config_.ValidateClientHello( |
| 174 message, client_address_, &clock_, | 178 message, |
| 179 client_address_, |
| 180 &clock_, |
| 175 new ValidateCallback(this, false, error_substr, called)); | 181 new ValidateCallback(this, false, error_substr, called)); |
| 176 } | 182 } |
| 177 | 183 |
| 178 void ProcessValidationResult(const CryptoHandshakeMessage& message, | 184 void ProcessValidationResult(const CryptoHandshakeMessage& message, |
| 179 const ValidateCallback::Result& result, | 185 const ValidateCallback::Result& result, |
| 180 bool should_succeed, | 186 bool should_succeed, |
| 181 const char* error_substr) { | 187 const char* error_substr) { |
| 182 string error_details; | 188 string error_details; |
| 183 QuicErrorCode error = config_.ProcessClientHello( | 189 QuicErrorCode error = |
| 184 result, 1 /* ConnectionId */, client_address_, | 190 config_.ProcessClientHello(result, |
| 185 supported_versions_.front(), supported_versions_, | 191 1 /* ConnectionId */, |
| 186 kInitialFlowControlWindowForTest, &clock_, rand_, ¶ms_, &out_, | 192 client_address_, |
| 187 &error_details); | 193 supported_versions_.front(), |
| 194 supported_versions_, |
| 195 kInitialFlowControlWindowForTest, |
| 196 &clock_, |
| 197 rand_, |
| 198 ¶ms_, |
| 199 &out_, |
| 200 &error_details); |
| 188 | 201 |
| 189 if (should_succeed) { | 202 if (should_succeed) { |
| 190 ASSERT_EQ(error, QUIC_NO_ERROR) | 203 ASSERT_EQ(error, QUIC_NO_ERROR) << "Message failed with error " |
| 191 << "Message failed with error " << error_details << ": " | 204 << error_details << ": " |
| 192 << message.DebugString(); | 205 << message.DebugString(); |
| 193 } else { | 206 } else { |
| 194 ASSERT_NE(error, QUIC_NO_ERROR) | 207 ASSERT_NE(error, QUIC_NO_ERROR) |
| 195 << "Message didn't fail: " << message.DebugString(); | 208 << "Message didn't fail: " << message.DebugString(); |
| 196 | 209 |
| 197 EXPECT_TRUE(error_details.find(error_substr) != string::npos) | 210 EXPECT_TRUE(error_details.find(error_substr) != string::npos) |
| 198 << error_substr << " not in " << error_details; | 211 << error_substr << " not in " << error_details; |
| 199 } | 212 } |
| 200 } | 213 } |
| 201 | 214 |
| 202 CryptoHandshakeMessage InchoateClientHello(const char* message_tag, ...) { | 215 CryptoHandshakeMessage InchoateClientHello(const char* message_tag, ...) { |
| 203 va_list ap; | 216 va_list ap; |
| 204 va_start(ap, message_tag); | 217 va_start(ap, message_tag); |
| 205 | 218 |
| 206 CryptoHandshakeMessage message = | 219 CryptoHandshakeMessage message = |
| 207 CryptoTestUtils::BuildMessage(message_tag, ap); | 220 CryptoTestUtils::BuildMessage(message_tag, ap); |
| 208 va_end(ap); | 221 va_end(ap); |
| 209 | 222 |
| 210 message.SetStringPiece(kPAD, string(kClientHelloMinimumSize, '-')); | 223 message.SetStringPiece(kPAD, string(kClientHelloMinimumSize, '-')); |
| 211 return message; | 224 return message; |
| 212 } | 225 } |
| 213 | 226 |
| 214 string GenerateNonce() { | 227 string GenerateNonce() { |
| 215 string nonce; | 228 string nonce; |
| 216 CryptoUtils::GenerateNonce( | 229 CryptoUtils::GenerateNonce( |
| 217 clock_.WallNow(), rand_, | 230 clock_.WallNow(), |
| 231 rand_, |
| 218 StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), | 232 StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), |
| 219 &nonce); | 233 &nonce); |
| 220 return nonce; | 234 return nonce; |
| 221 } | 235 } |
| 222 | 236 |
| 223 protected: | 237 protected: |
| 224 QuicRandom* const rand_; | 238 QuicRandom* const rand_; |
| 225 MockClock clock_; | 239 MockClock clock_; |
| 226 const IPEndPoint client_address_; | 240 const IPEndPoint client_address_; |
| 227 QuicVersionVector supported_versions_; | 241 QuicVersionVector supported_versions_; |
| 228 string client_version_; | 242 string client_version_; |
| 229 QuicCryptoServerConfig config_; | 243 QuicCryptoServerConfig config_; |
| 230 QuicCryptoServerConfig::ConfigOptions config_options_; | 244 QuicCryptoServerConfig::ConfigOptions config_options_; |
| 231 QuicCryptoNegotiatedParameters params_; | 245 QuicCryptoNegotiatedParameters params_; |
| 232 CryptoHandshakeMessage out_; | 246 CryptoHandshakeMessage out_; |
| 233 uint8 orbit_[kOrbitSize]; | 247 uint8 orbit_[kOrbitSize]; |
| 234 | 248 |
| 235 // These strings contain hex escaped values from the server suitable for | 249 // These strings contain hex escaped values from the server suitable for |
| 236 // passing to |InchoateClientHello| when constructing client hello messages. | 250 // passing to |InchoateClientHello| when constructing client hello messages. |
| 237 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; | 251 string nonce_hex_, pub_hex_, srct_hex_, scid_hex_; |
| 238 scoped_ptr<CryptoHandshakeMessage> server_config_; | 252 scoped_ptr<CryptoHandshakeMessage> server_config_; |
| 239 }; | 253 }; |
| 240 | 254 |
| 241 TEST_F(CryptoServerTest, BadSNI) { | 255 TEST_F(CryptoServerTest, BadSNI) { |
| 242 static const char* kBadSNIs[] = { | 256 static const char* kBadSNIs[] = { |
| 243 "", | 257 "", "foo", "#00", "#ff00", "127.0.0.1", "ffee::1", |
| 244 "foo", | |
| 245 "#00", | |
| 246 "#ff00", | |
| 247 "127.0.0.1", | |
| 248 "ffee::1", | |
| 249 }; | 258 }; |
| 250 | 259 |
| 251 string client_version = QuicUtils::TagToString( | 260 string client_version = |
| 252 QuicVersionToQuicTag(supported_versions_.front())); | 261 QuicUtils::TagToString(QuicVersionToQuicTag(supported_versions_.front())); |
| 253 | 262 |
| 254 for (size_t i = 0; i < arraysize(kBadSNIs); i++) { | 263 for (size_t i = 0; i < arraysize(kBadSNIs); i++) { |
| 255 ShouldFailMentioning("SNI", InchoateClientHello( | 264 ShouldFailMentioning( |
| 256 "CHLO", | 265 "SNI", |
| 257 "SNI", kBadSNIs[i], | 266 InchoateClientHello( |
| 258 "VER\0", client_version.data(), | 267 "CHLO", "SNI", kBadSNIs[i], "VER\0", client_version.data(), NULL)); |
| 259 NULL)); | |
| 260 } | 268 } |
| 261 } | 269 } |
| 262 | 270 |
| 263 // TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. | 271 // TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource. |
| 264 TEST_F(CryptoServerTest, DISABLED_DefaultCert) { | 272 TEST_F(CryptoServerTest, DISABLED_DefaultCert) { |
| 265 // Check that the server replies with a default certificate when no SNI is | 273 // Check that the server replies with a default certificate when no SNI is |
| 266 // specified. | 274 // specified. |
| 267 ShouldSucceed(InchoateClientHello( | 275 ShouldSucceed(InchoateClientHello("CHLO", |
| 268 "CHLO", | 276 "AEAD", |
| 269 "AEAD", "AESG", | 277 "AESG", |
| 270 "KEXS", "C255", | 278 "KEXS", |
| 271 "SCID", scid_hex_.c_str(), | 279 "C255", |
| 272 "#004b5453", srct_hex_.c_str(), | 280 "SCID", |
| 273 "PUBS", pub_hex_.c_str(), | 281 scid_hex_.c_str(), |
| 274 "NONC", nonce_hex_.c_str(), | 282 "#004b5453", |
| 275 "$padding", static_cast<int>(kClientHelloMinimumSize), | 283 srct_hex_.c_str(), |
| 276 "PDMD", "X509", | 284 "PUBS", |
| 277 "VER\0", client_version_.data(), | 285 pub_hex_.c_str(), |
| 278 NULL)); | 286 "NONC", |
| 287 nonce_hex_.c_str(), |
| 288 "$padding", |
| 289 static_cast<int>(kClientHelloMinimumSize), |
| 290 "PDMD", |
| 291 "X509", |
| 292 "VER\0", |
| 293 client_version_.data(), |
| 294 NULL)); |
| 279 | 295 |
| 280 StringPiece cert, proof; | 296 StringPiece cert, proof; |
| 281 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); | 297 EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); |
| 282 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); | 298 EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); |
| 283 EXPECT_NE(0u, cert.size()); | 299 EXPECT_NE(0u, cert.size()); |
| 284 EXPECT_NE(0u, proof.size()); | 300 EXPECT_NE(0u, proof.size()); |
| 285 } | 301 } |
| 286 | 302 |
| 287 TEST_F(CryptoServerTest, TooSmall) { | 303 TEST_F(CryptoServerTest, TooSmall) { |
| 288 ShouldFailMentioning("too small", CryptoTestUtils::Message( | 304 ShouldFailMentioning( |
| 289 "CHLO", | 305 "too small", |
| 290 "VER\0", client_version_.data(), | 306 CryptoTestUtils::Message("CHLO", "VER\0", client_version_.data(), NULL)); |
| 291 NULL)); | |
| 292 } | 307 } |
| 293 | 308 |
| 294 TEST_F(CryptoServerTest, BadSourceAddressToken) { | 309 TEST_F(CryptoServerTest, BadSourceAddressToken) { |
| 295 // Invalid source-address tokens should be ignored. | 310 // Invalid source-address tokens should be ignored. |
| 296 static const char* kBadSourceAddressTokens[] = { | 311 static const char* kBadSourceAddressTokens[] = { |
| 297 "", | 312 "", "foo", "#0000", "#0000000000000000000000000000000000000000", |
| 298 "foo", | |
| 299 "#0000", | |
| 300 "#0000000000000000000000000000000000000000", | |
| 301 }; | 313 }; |
| 302 | 314 |
| 303 for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { | 315 for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) { |
| 304 ShouldSucceed(InchoateClientHello( | 316 ShouldSucceed(InchoateClientHello("CHLO", |
| 305 "CHLO", | 317 "STK", |
| 306 "STK", kBadSourceAddressTokens[i], | 318 kBadSourceAddressTokens[i], |
| 307 "VER\0", client_version_.data(), | 319 "VER\0", |
| 308 NULL)); | 320 client_version_.data(), |
| 321 NULL)); |
| 309 } | 322 } |
| 310 } | 323 } |
| 311 | 324 |
| 312 TEST_F(CryptoServerTest, BadClientNonce) { | 325 TEST_F(CryptoServerTest, BadClientNonce) { |
| 313 // Invalid nonces should be ignored. | 326 // Invalid nonces should be ignored. |
| 314 static const char* kBadNonces[] = { | 327 static const char* kBadNonces[] = { |
| 315 "", | 328 "", "#0000", "#0000000000000000000000000000000000000000", |
| 316 "#0000", | |
| 317 "#0000000000000000000000000000000000000000", | |
| 318 }; | 329 }; |
| 319 | 330 |
| 320 for (size_t i = 0; i < arraysize(kBadNonces); i++) { | 331 for (size_t i = 0; i < arraysize(kBadNonces); i++) { |
| 321 ShouldSucceed(InchoateClientHello( | 332 ShouldSucceed(InchoateClientHello( |
| 322 "CHLO", | 333 "CHLO", "NONC", kBadNonces[i], "VER\0", client_version_.data(), NULL)); |
| 323 "NONC", kBadNonces[i], | |
| 324 "VER\0", client_version_.data(), | |
| 325 NULL)); | |
| 326 } | 334 } |
| 327 } | 335 } |
| 328 | 336 |
| 329 TEST_F(CryptoServerTest, DowngradeAttack) { | 337 TEST_F(CryptoServerTest, DowngradeAttack) { |
| 330 if (supported_versions_.size() == 1) { | 338 if (supported_versions_.size() == 1) { |
| 331 // No downgrade attack is possible if the server only supports one version. | 339 // No downgrade attack is possible if the server only supports one version. |
| 332 return; | 340 return; |
| 333 } | 341 } |
| 334 // Set the client's preferred version to a supported version that | 342 // Set the client's preferred version to a supported version that |
| 335 // is not the "current" version (supported_versions_.front()). | 343 // is not the "current" version (supported_versions_.front()). |
| 336 string bad_version = QuicUtils::TagToString( | 344 string bad_version = |
| 337 QuicVersionToQuicTag(supported_versions_.back())); | 345 QuicUtils::TagToString(QuicVersionToQuicTag(supported_versions_.back())); |
| 338 | 346 |
| 339 ShouldFailMentioning("Downgrade", InchoateClientHello( | 347 ShouldFailMentioning( |
| 340 "CHLO", | 348 "Downgrade", |
| 341 "VER\0", bad_version.data(), | 349 InchoateClientHello("CHLO", "VER\0", bad_version.data(), NULL)); |
| 342 NULL)); | |
| 343 } | 350 } |
| 344 | 351 |
| 345 TEST_F(CryptoServerTest, ReplayProtection) { | 352 TEST_F(CryptoServerTest, ReplayProtection) { |
| 346 // This tests that disabling replay protection works. | 353 // This tests that disabling replay protection works. |
| 347 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 354 CryptoHandshakeMessage msg = |
| 348 "CHLO", | 355 CryptoTestUtils::Message("CHLO", |
| 349 "AEAD", "AESG", | 356 "AEAD", |
| 350 "KEXS", "C255", | 357 "AESG", |
| 351 "SCID", scid_hex_.c_str(), | 358 "KEXS", |
| 352 "#004b5453", srct_hex_.c_str(), | 359 "C255", |
| 353 "PUBS", pub_hex_.c_str(), | 360 "SCID", |
| 354 "NONC", nonce_hex_.c_str(), | 361 scid_hex_.c_str(), |
| 355 "VER\0", client_version_.data(), | 362 "#004b5453", |
| 356 "$padding", static_cast<int>(kClientHelloMinimumSize), | 363 srct_hex_.c_str(), |
| 357 NULL); | 364 "PUBS", |
| 365 pub_hex_.c_str(), |
| 366 "NONC", |
| 367 nonce_hex_.c_str(), |
| 368 "VER\0", |
| 369 client_version_.data(), |
| 370 "$padding", |
| 371 static_cast<int>(kClientHelloMinimumSize), |
| 372 NULL); |
| 358 ShouldSucceed(msg); | 373 ShouldSucceed(msg); |
| 359 // The message should be rejected because the strike-register is still | 374 // The message should be rejected because the strike-register is still |
| 360 // quiescent. | 375 // quiescent. |
| 361 ASSERT_EQ(kREJ, out_.tag()); | 376 ASSERT_EQ(kREJ, out_.tag()); |
| 362 | 377 |
| 363 config_.set_replay_protection(false); | 378 config_.set_replay_protection(false); |
| 364 | 379 |
| 365 ShouldSucceed(msg); | 380 ShouldSucceed(msg); |
| 366 // The message should be accepted now. | 381 // The message should be accepted now. |
| 367 ASSERT_EQ(kSHLO, out_.tag()); | 382 ASSERT_EQ(kSHLO, out_.tag()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 scoped_ptr<CryptoHandshakeMessage> scfg_b( | 422 scoped_ptr<CryptoHandshakeMessage> scfg_b( |
| 408 b.AddDefaultConfig(&rand_b, &clock, options)); | 423 b.AddDefaultConfig(&rand_b, &clock, options)); |
| 409 | 424 |
| 410 StringPiece scid_a, scid_b; | 425 StringPiece scid_a, scid_b; |
| 411 EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a)); | 426 EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a)); |
| 412 EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b)); | 427 EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b)); |
| 413 | 428 |
| 414 EXPECT_NE(scid_a, scid_b); | 429 EXPECT_NE(scid_a, scid_b); |
| 415 } | 430 } |
| 416 | 431 |
| 417 | |
| 418 TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) { | 432 TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) { |
| 419 MockRandom rand_a; | 433 MockRandom rand_a; |
| 420 const QuicCryptoServerConfig::ConfigOptions options; | 434 const QuicCryptoServerConfig::ConfigOptions options; |
| 421 MockClock clock; | 435 MockClock clock; |
| 422 | 436 |
| 423 QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a); | 437 QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a); |
| 424 scoped_ptr<CryptoHandshakeMessage> scfg( | 438 scoped_ptr<CryptoHandshakeMessage> scfg( |
| 425 a.AddDefaultConfig(&rand_a, &clock, options)); | 439 a.AddDefaultConfig(&rand_a, &clock, options)); |
| 426 | 440 |
| 427 StringPiece scid; | 441 StringPiece scid; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 444 } | 458 } |
| 445 | 459 |
| 446 class CryptoServerTestNoConfig : public CryptoServerTest { | 460 class CryptoServerTestNoConfig : public CryptoServerTest { |
| 447 public: | 461 public: |
| 448 virtual void SetUp() { | 462 virtual void SetUp() { |
| 449 // Deliberately don't add a config so that we can test this situation. | 463 // Deliberately don't add a config so that we can test this situation. |
| 450 } | 464 } |
| 451 }; | 465 }; |
| 452 | 466 |
| 453 TEST_F(CryptoServerTestNoConfig, DontCrash) { | 467 TEST_F(CryptoServerTestNoConfig, DontCrash) { |
| 454 ShouldFailMentioning("No config", InchoateClientHello( | 468 ShouldFailMentioning( |
| 455 "CHLO", | 469 "No config", |
| 456 "VER\0", client_version_.data(), | 470 InchoateClientHello("CHLO", "VER\0", client_version_.data(), NULL)); |
| 457 NULL)); | |
| 458 } | 471 } |
| 459 | 472 |
| 460 class AsyncStrikeServerVerificationTest : public CryptoServerTest { | 473 class AsyncStrikeServerVerificationTest : public CryptoServerTest { |
| 461 protected: | 474 protected: |
| 462 AsyncStrikeServerVerificationTest() { | 475 AsyncStrikeServerVerificationTest() {} |
| 463 } | |
| 464 | 476 |
| 465 virtual void SetUp() { | 477 virtual void SetUp() { |
| 466 const string kOrbit = "12345678"; | 478 const string kOrbit = "12345678"; |
| 467 config_options_.orbit = kOrbit; | 479 config_options_.orbit = kOrbit; |
| 468 strike_register_client_ = new DelayedVerifyStrikeRegisterClient( | 480 strike_register_client_ = new DelayedVerifyStrikeRegisterClient( |
| 469 10000, // strike_register_max_entries | 481 10000, // strike_register_max_entries |
| 470 static_cast<uint32>(clock_.WallNow().ToUNIXSeconds()), | 482 static_cast<uint32>(clock_.WallNow().ToUNIXSeconds()), |
| 471 60, // strike_register_window_secs | 483 60, // strike_register_window_secs |
| 472 reinterpret_cast<const uint8 *>(kOrbit.data()), | 484 reinterpret_cast<const uint8*>(kOrbit.data()), |
| 473 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); | 485 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); |
| 474 config_.SetStrikeRegisterClient(strike_register_client_); | 486 config_.SetStrikeRegisterClient(strike_register_client_); |
| 475 CryptoServerTest::SetUp(); | 487 CryptoServerTest::SetUp(); |
| 476 strike_register_client_->StartDelayingVerification(); | 488 strike_register_client_->StartDelayingVerification(); |
| 477 } | 489 } |
| 478 | 490 |
| 479 DelayedVerifyStrikeRegisterClient* strike_register_client_; | 491 DelayedVerifyStrikeRegisterClient* strike_register_client_; |
| 480 }; | 492 }; |
| 481 | 493 |
| 482 TEST_F(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { | 494 TEST_F(AsyncStrikeServerVerificationTest, AsyncReplayProtection) { |
| 483 // This tests async validation with a strike register works. | 495 // This tests async validation with a strike register works. |
| 484 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 496 CryptoHandshakeMessage msg = |
| 485 "CHLO", | 497 CryptoTestUtils::Message("CHLO", |
| 486 "AEAD", "AESG", | 498 "AEAD", |
| 487 "KEXS", "C255", | 499 "AESG", |
| 488 "SCID", scid_hex_.c_str(), | 500 "KEXS", |
| 489 "#004b5453", srct_hex_.c_str(), | 501 "C255", |
| 490 "PUBS", pub_hex_.c_str(), | 502 "SCID", |
| 491 "NONC", nonce_hex_.c_str(), | 503 scid_hex_.c_str(), |
| 492 "VER\0", client_version_.data(), | 504 "#004b5453", |
| 493 "$padding", static_cast<int>(kClientHelloMinimumSize), | 505 srct_hex_.c_str(), |
| 494 NULL); | 506 "PUBS", |
| 507 pub_hex_.c_str(), |
| 508 "NONC", |
| 509 nonce_hex_.c_str(), |
| 510 "VER\0", |
| 511 client_version_.data(), |
| 512 "$padding", |
| 513 static_cast<int>(kClientHelloMinimumSize), |
| 514 NULL); |
| 495 | 515 |
| 496 // Clear the message tag. | 516 // Clear the message tag. |
| 497 out_.set_tag(0); | 517 out_.set_tag(0); |
| 498 | 518 |
| 499 bool called = false; | 519 bool called = false; |
| 500 RunValidate(msg, new ValidateCallback(this, true, "", &called)); | 520 RunValidate(msg, new ValidateCallback(this, true, "", &called)); |
| 501 // The verification request was queued. | 521 // The verification request was queued. |
| 502 ASSERT_FALSE(called); | 522 ASSERT_FALSE(called); |
| 503 EXPECT_EQ(0u, out_.tag()); | 523 EXPECT_EQ(0u, out_.tag()); |
| 504 EXPECT_EQ(1, strike_register_client_->PendingVerifications()); | 524 EXPECT_EQ(1, strike_register_client_->PendingVerifications()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 518 | 538 |
| 519 strike_register_client_->RunPendingVerifications(); | 539 strike_register_client_->RunPendingVerifications(); |
| 520 ASSERT_TRUE(called); | 540 ASSERT_TRUE(called); |
| 521 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); | 541 EXPECT_EQ(0, strike_register_client_->PendingVerifications()); |
| 522 // The message should be rejected now. | 542 // The message should be rejected now. |
| 523 EXPECT_EQ(kREJ, out_.tag()); | 543 EXPECT_EQ(kREJ, out_.tag()); |
| 524 } | 544 } |
| 525 | 545 |
| 526 TEST_F(CryptoServerTest, InitialFlowControlWindow) { | 546 TEST_F(CryptoServerTest, InitialFlowControlWindow) { |
| 527 // Test that the SHLO contains a value for initial flow control window. | 547 // Test that the SHLO contains a value for initial flow control window. |
| 528 CryptoHandshakeMessage msg = CryptoTestUtils::Message( | 548 CryptoHandshakeMessage msg = |
| 529 "CHLO", | 549 CryptoTestUtils::Message("CHLO", |
| 530 "AEAD", "AESG", | 550 "AEAD", |
| 531 "KEXS", "C255", | 551 "AESG", |
| 532 "SCID", scid_hex_.c_str(), | 552 "KEXS", |
| 533 "#004b5453", srct_hex_.c_str(), | 553 "C255", |
| 534 "PUBS", pub_hex_.c_str(), | 554 "SCID", |
| 535 "NONC", nonce_hex_.c_str(), | 555 scid_hex_.c_str(), |
| 536 "VER\0", client_version_.data(), | 556 "#004b5453", |
| 537 "$padding", static_cast<int>(kClientHelloMinimumSize), | 557 srct_hex_.c_str(), |
| 538 NULL); | 558 "PUBS", |
| 559 pub_hex_.c_str(), |
| 560 "NONC", |
| 561 nonce_hex_.c_str(), |
| 562 "VER\0", |
| 563 client_version_.data(), |
| 564 "$padding", |
| 565 static_cast<int>(kClientHelloMinimumSize), |
| 566 NULL); |
| 539 ShouldSucceed(msg); | 567 ShouldSucceed(msg); |
| 540 // The message should be rejected because the strike-register is still | 568 // The message should be rejected because the strike-register is still |
| 541 // quiescent. | 569 // quiescent. |
| 542 ASSERT_EQ(kREJ, out_.tag()); | 570 ASSERT_EQ(kREJ, out_.tag()); |
| 543 config_.set_replay_protection(false); | 571 config_.set_replay_protection(false); |
| 544 | 572 |
| 545 // The message should be accepted now. | 573 // The message should be accepted now. |
| 546 ShouldSucceed(msg); | 574 ShouldSucceed(msg); |
| 547 ASSERT_EQ(kSHLO, out_.tag()); | 575 ASSERT_EQ(kSHLO, out_.tag()); |
| 548 CheckServerHello(out_); | 576 CheckServerHello(out_); |
| 549 | 577 |
| 550 // Ensure that the kIFCW tag is populated correctly. | 578 // Ensure that the kIFCW tag is populated correctly. |
| 551 QuicTag ifcw; | 579 QuicTag ifcw; |
| 552 EXPECT_EQ(QUIC_NO_ERROR, out_.GetUint32(kIFCW, &ifcw)); | 580 EXPECT_EQ(QUIC_NO_ERROR, out_.GetUint32(kIFCW, &ifcw)); |
| 553 EXPECT_EQ(kInitialFlowControlWindowForTest, ifcw); | 581 EXPECT_EQ(kInitialFlowControlWindowForTest, ifcw); |
| 554 } | 582 } |
| 555 | 583 |
| 556 } // namespace test | 584 } // namespace test |
| 557 } // namespace net | 585 } // namespace net |
| OLD | NEW |