Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Unified Diff: net/quic/crypto/crypto_server_test.cc

Issue 331143006: QUIC Crypto - return the reasons for reject message. Reject reason (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase with TOT Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 f1892d3b6ac7813f9029df6a82829ef32ccddfca..6eae4c120bdb7d593055a7c778f09ba722b86a9c 100644
--- a/net/quic/crypto/crypto_server_test.cc
+++ b/net/quic/crypto/crypto_server_test.cc
@@ -2,12 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <ostream>
+#include <vector>
+
#include "base/basictypes.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/secure_hash.h"
#include "net/quic/crypto/crypto_utils.h"
#include "net/quic/crypto/quic_crypto_server_config.h"
#include "net/quic/crypto/quic_random.h"
+#include "net/quic/quic_flags.h"
#include "net/quic/quic_socket_address_coder.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/crypto_test_utils.h"
@@ -18,7 +22,9 @@
#include "testing/gtest/include/gtest/gtest.h"
using base::StringPiece;
+using std::ostream;
using std::string;
+using std::vector;
namespace net {
namespace test {
@@ -36,7 +42,40 @@ class QuicCryptoServerConfigPeer {
QuicCryptoServerConfig* server_config_;
};
-class CryptoServerTest : public ::testing::Test {
+// Run tests with combinations of
+// {FLAGS_use_early_return_when_verifying_chlo,
+// FLAGS_send_quic_crypto_reject_reason}.
+struct TestParams {
+ TestParams(bool use_early_return_when_verifying_chlo,
+ bool send_quic_crypto_reject_reason)
+ : use_early_return_when_verifying_chlo(
+ use_early_return_when_verifying_chlo),
+ send_quic_crypto_reject_reason(send_quic_crypto_reject_reason) {
+ }
+
+ friend ostream& operator<<(ostream& os, const TestParams& p) {
+ os << "{ use_early_return_when_verifying_chlo: "
+ << p.use_early_return_when_verifying_chlo
+ << " send_quic_crypto_reject_reason: "
+ << p.send_quic_crypto_reject_reason << " }";
+ return os;
+ }
+
+ bool use_early_return_when_verifying_chlo;
+ bool send_quic_crypto_reject_reason;
+};
+
+// Constructs various test permutations.
+vector<TestParams> GetTestParams() {
+ vector<TestParams> params;
+ params.push_back(TestParams(false, false));
+ params.push_back(TestParams(false, true));
+ params.push_back(TestParams(true, false));
+ params.push_back(TestParams(true, true));
+ return params;
+}
+
+class CryptoServerTest : public ::testing::TestWithParam<TestParams> {
public:
CryptoServerTest()
: rand_(QuicRandom::GetInstance()),
@@ -46,6 +85,11 @@ class CryptoServerTest : public ::testing::Test {
supported_versions_ = QuicSupportedVersions();
client_version_ = QuicUtils::TagToString(
QuicVersionToQuicTag(supported_versions_.front()));
+
+ FLAGS_use_early_return_when_verifying_chlo =
+ GetParam().use_early_return_when_verifying_chlo;
+ FLAGS_send_quic_crypto_reject_reason =
+ GetParam().send_quic_crypto_reject_reason;
}
virtual void SetUp() {
@@ -78,6 +122,10 @@ class CryptoServerTest : public ::testing::Test {
// The message should be rejected because the source-address token is
// missing.
ASSERT_EQ(kREJ, out_.tag());
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
StringPiece srct;
ASSERT_TRUE(out_.GetStringPiece(kSourceAddressTokenTag, &srct));
@@ -219,6 +267,29 @@ class CryptoServerTest : public ::testing::Test {
return nonce;
}
+ void CheckRejectReasons(
+ const HandshakeFailureReason* expected_handshake_failures,
+ size_t expected_count) {
+ const QuicTag* reject_reason_tags;
+ size_t num_reject_reasons;
+ QuicErrorCode error_code = out_.GetTaglist(
+ kRejectReason, &reject_reason_tags, &num_reject_reasons);
+ if (!FLAGS_send_quic_crypto_reject_reason) {
+ ASSERT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error_code);
+ return;
+ }
+ ASSERT_EQ(QUIC_NO_ERROR, error_code);
+
+ if (FLAGS_use_early_return_when_verifying_chlo) {
+ EXPECT_EQ(1u, num_reject_reasons);
+ } else {
+ EXPECT_EQ(expected_count, num_reject_reasons);
+ }
+ for (size_t i = 0; i < num_reject_reasons; ++i) {
+ EXPECT_EQ(expected_handshake_failures[i], reject_reason_tags[i]);
+ }
+ }
+
protected:
QuicRandom* const rand_;
MockClock clock_;
@@ -237,7 +308,14 @@ class CryptoServerTest : public ::testing::Test {
scoped_ptr<CryptoHandshakeMessage> server_config_;
};
-TEST_F(CryptoServerTest, BadSNI) {
+// Run all CryptoServerTest with all combinations of
+// FLAGS_use_early_return_when_verifying_chlo and
+// FLAGS_send_quic_crypto_reject_reason.
+INSTANTIATE_TEST_CASE_P(CryptoServerTests,
+ CryptoServerTest,
+ ::testing::ValuesIn(GetTestParams()));
+
+TEST_P(CryptoServerTest, BadSNI) {
static const char* kBadSNIs[] = {
"",
"foo",
@@ -256,6 +334,10 @@ TEST_F(CryptoServerTest, BadSNI) {
"SNI", kBadSNIs[i],
"VER\0", client_version.data(),
NULL));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
}
@@ -281,16 +363,24 @@ TEST_F(CryptoServerTest, DISABLED_DefaultCert) {
EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
EXPECT_NE(0u, cert.size());
EXPECT_NE(0u, proof.size());
+ const HandshakeFailureReason kRejectReasons[] = {
+ CLIENT_NONCE_UNKNOWN_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
-TEST_F(CryptoServerTest, TooSmall) {
+TEST_P(CryptoServerTest, TooSmall) {
ShouldFailMentioning("too small", CryptoTestUtils::Message(
"CHLO",
"VER\0", client_version_.data(),
NULL));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
-TEST_F(CryptoServerTest, BadSourceAddressToken) {
+TEST_P(CryptoServerTest, BadSourceAddressToken) {
// Invalid source-address tokens should be ignored.
static const char* kBadSourceAddressTokens[] = {
"",
@@ -305,10 +395,14 @@ TEST_F(CryptoServerTest, BadSourceAddressToken) {
"STK", kBadSourceAddressTokens[i],
"VER\0", client_version_.data(),
NULL));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
}
-TEST_F(CryptoServerTest, BadClientNonce) {
+TEST_P(CryptoServerTest, BadClientNonce) {
// Invalid nonces should be ignored.
static const char* kBadNonces[] = {
"",
@@ -322,10 +416,14 @@ TEST_F(CryptoServerTest, BadClientNonce) {
"NONC", kBadNonces[i],
"VER\0", client_version_.data(),
NULL));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
}
-TEST_F(CryptoServerTest, DowngradeAttack) {
+TEST_P(CryptoServerTest, DowngradeAttack) {
if (supported_versions_.size() == 1) {
// No downgrade attack is possible if the server only supports one version.
return;
@@ -339,9 +437,101 @@ TEST_F(CryptoServerTest, DowngradeAttack) {
"CHLO",
"VER\0", bad_version.data(),
NULL));
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_INCHOATE_HELLO_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
-TEST_F(CryptoServerTest, ReplayProtection) {
+TEST_P(CryptoServerTest, CorruptServerConfig) {
+ // This tests corrupted server config.
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", (string(1, 'X') + scid_hex_).c_str(),
+ "#004b5453", srct_hex_.c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_.data(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ NULL);
+ ShouldSucceed(msg);
+ ASSERT_EQ(kREJ, out_.tag());
+ const HandshakeFailureReason kRejectReasons[] = {
+ SERVER_CONFIG_UNKNOWN_CONFIG_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptSourceAddressToken) {
+ // This tests corrupted source address token.
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", (string(1, 'X') + srct_hex_).c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", nonce_hex_.c_str(),
+ "VER\0", client_version_.data(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ NULL);
+ ShouldSucceed(msg);
+ ASSERT_EQ(kREJ, out_.tag());
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptClientNonceAndSourceAddressToken) {
+ // This test corrupts client nonce and source address token.
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", (string(1, 'X') + srct_hex_).c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", (string(1, 'X') + nonce_hex_).c_str(),
+ "VER\0", client_version_.data(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ NULL);
+ ShouldSucceed(msg);
+ ASSERT_EQ(kREJ, out_.tag());
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
+ CLIENT_NONCE_INVALID_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, CorruptMultipleTags) {
+ // This test corrupts client nonce, server nonce and source address token.
+ CryptoHandshakeMessage msg = CryptoTestUtils::Message(
+ "CHLO",
+ "AEAD", "AESG",
+ "KEXS", "C255",
+ "SCID", scid_hex_.c_str(),
+ "#004b5453", (string(1, 'X') + srct_hex_).c_str(),
+ "PUBS", pub_hex_.c_str(),
+ "NONC", (string(1, 'X') + nonce_hex_).c_str(),
+ "SNO\0", (string(1, 'X') + nonce_hex_).c_str(),
+ "VER\0", client_version_.data(),
+ "$padding", static_cast<int>(kClientHelloMinimumSize),
+ NULL);
+ ShouldSucceed(msg);
+ ASSERT_EQ(kREJ, out_.tag());
+ const HandshakeFailureReason kRejectReasons[] = {
+ SOURCE_ADDRESS_TOKEN_DECRYPTION_FAILURE,
+ CLIENT_NONCE_INVALID_FAILURE,
+ SERVER_NONCE_DECRYPTION_FAILURE,
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+}
+
+TEST_P(CryptoServerTest, ReplayProtection) {
// This tests that disabling replay protection works.
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",
@@ -359,6 +549,11 @@ TEST_F(CryptoServerTest, ReplayProtection) {
// quiescent.
ASSERT_EQ(kREJ, out_.tag());
+ const HandshakeFailureReason kRejectReasons[] = {
+ CLIENT_NONCE_UNKNOWN_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
+
config_.set_replay_protection(false);
ShouldSucceed(msg);
@@ -449,11 +644,16 @@ class CryptoServerTestNoConfig : public CryptoServerTest {
}
};
-TEST_F(CryptoServerTestNoConfig, DontCrash) {
- ShouldFailMentioning("No config", InchoateClientHello(
- "CHLO",
- "VER\0", client_version_.data(),
- NULL));
+TEST_P(CryptoServerTestNoConfig, DontCrash) {
+ ShouldFailMentioning("No config", InchoateClientHello(
+ "CHLO",
+ "VER\0", client_version_.data(),
+ NULL));
+
+ const HandshakeFailureReason kRejectReasons[] = {
+ CLIENT_NONCE_UNKNOWN_FAILURE
+ };
+ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}
class AsyncStrikeServerVerificationTest : public CryptoServerTest {
@@ -478,7 +678,7 @@ class AsyncStrikeServerVerificationTest : public CryptoServerTest {
DelayedVerifyStrikeRegisterClient* strike_register_client_;
};
-TEST_F(AsyncStrikeServerVerificationTest, AsyncReplayProtection) {
+TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) {
// This tests async validation with a strike register works.
CryptoHandshakeMessage msg = CryptoTestUtils::Message(
"CHLO",

Powered by Google App Engine
This is Rietveld 408576698