Index: net/quic/crypto/crypto_server_test.cc |
diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc |
index 2d5c9f4d2b0b02ffe6225675424bc17cb6ee3605..0a5a60358a82ba4bcc8e6d24318468064d57c9fe 100644 |
--- a/net/quic/crypto/crypto_server_test.cc |
+++ b/net/quic/crypto/crypto_server_test.cc |
@@ -2,12 +2,15 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "base/strings/string_number_conversions.h" |
#include "net/quic/crypto/crypto_server_config.h" |
+#include "net/quic/crypto/crypto_utils.h" |
#include "net/quic/crypto/quic_random.h" |
#include "net/quic/test_tools/crypto_test_utils.h" |
#include "net/quic/test_tools/mock_clock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
+using base::StringPiece; |
using std::string; |
namespace net { |
@@ -26,6 +29,11 @@ class CryptoServerTest : public ::testing::Test { |
scoped_ptr<CryptoHandshakeMessage> msg( |
config_.AddDefaultConfig(rand_, &clock_, |
QuicCryptoServerConfig::ConfigOptions())); |
+ |
+ StringPiece orbit; |
+ CHECK(msg->GetStringPiece(kORBT, &orbit)); |
+ CHECK_EQ(sizeof(orbit_), orbit.size()); |
+ memcpy(orbit_, orbit.data(), orbit.size()); |
} |
void ShouldSucceed(const CryptoHandshakeMessage& message) { |
@@ -65,7 +73,16 @@ class CryptoServerTest : public ::testing::Test { |
return message; |
} |
- private: |
+ string GenerateNonce() { |
+ string nonce; |
+ CryptoUtils::GenerateNonce( |
+ clock_.WallNow(), rand_, |
+ StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)), |
+ &nonce); |
+ return nonce; |
+ } |
+ |
+ protected: |
QuicRandom* const rand_; |
MockClock clock_; |
QuicCryptoServerConfig config_; |
@@ -73,6 +90,7 @@ class CryptoServerTest : public ::testing::Test { |
CryptoHandshakeMessage out_; |
IPAddressNumber ip_; |
IPEndPoint addr_; |
+ uint8 orbit_[kOrbitSize]; |
}; |
TEST_F(CryptoServerTest, BadSNI) { |
@@ -132,6 +150,68 @@ TEST_F(CryptoServerTest, BadClientNonce) { |
} |
} |
+TEST_F(CryptoServerTest, ReplayProtection) { |
+ // This tests that disabling replay protection works. |
+ |
+ char public_value[32]; |
+ memset(public_value, 42, sizeof(public_value)); |
+ |
+ const string nonce_str = GenerateNonce(); |
+ const string nonce("#" + base::HexEncode(nonce_str.data(), |
+ nonce_str.size())); |
+ const string pub("#" + base::HexEncode(public_value, sizeof(public_value))); |
+ |
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message( |
+ "CHLO", |
+ "AEAD", "AESG", |
+ "KEXS", "C255", |
+ "PUBS", pub.c_str(), |
+ "NONC", nonce.c_str(), |
+ "$padding", static_cast<int>(kClientHelloMinimumSize), |
+ NULL); |
+ ShouldSucceed(msg); |
+ // The message should be rejected because the source-address token is missing. |
+ ASSERT_EQ(kREJ, out_.tag()); |
+ |
+ StringPiece srct; |
+ ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct)); |
+ const string srct_hex = "#" + base::HexEncode(srct.data(), srct.size()); |
+ |
+ StringPiece scfg; |
+ ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg)); |
+ scoped_ptr<CryptoHandshakeMessage> server_config( |
+ CryptoFramer::ParseMessage(scfg)); |
+ |
+ StringPiece scid; |
+ ASSERT_TRUE(server_config->GetStringPiece(kSCID, &scid)); |
+ const string scid_hex("#" + base::HexEncode(scid.data(), scid.size())); |
+ |
+ msg = CryptoTestUtils::Message( |
+ "CHLO", |
+ "AEAD", "AESG", |
+ "KEXS", "C255", |
+ "SCID", scid_hex.c_str(), |
+ "#004b5453", srct_hex.c_str(), |
+ "PUBS", pub.c_str(), |
+ "NONC", nonce.c_str(), |
+ "$padding", static_cast<int>(kClientHelloMinimumSize), |
+ NULL); |
+ ShouldSucceed(msg); |
+ // The message should be rejected because the strike-register is still |
+ // quiescent. |
+ ASSERT_EQ(kREJ, out_.tag()); |
+ |
+ config_.set_replay_protection(false); |
+ |
+ ShouldSucceed(msg); |
+ // The message should be accepted now. |
+ ASSERT_EQ(kSHLO, out_.tag()); |
+ |
+ ShouldSucceed(msg); |
+ // The message should accepted twice when replay protection is off. |
+ ASSERT_EQ(kSHLO, out_.tag()); |
+} |
+ |
class CryptoServerTestNoConfig : public CryptoServerTest { |
public: |
virtual void SetUp() { |