// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// 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"
#include "net/quic/test_tools/delayed_verify_strike_register_client.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_random.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::StringPiece;
using std::ostream;
using std::string;
using std::vector;

namespace net {
namespace test {

class QuicCryptoServerConfigPeer {
 public:
  explicit QuicCryptoServerConfigPeer(QuicCryptoServerConfig* server_config)
      : server_config_(server_config) {}

  base::Lock* GetStrikeRegisterClientLock() {
    return &server_config_->strike_register_client_lock_;
  }

 private:
  QuicCryptoServerConfig* server_config_;
};

// 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()),
        client_address_(Loopback4(), 1234),
        config_(QuicCryptoServerConfig::TESTING, rand_) {
    config_.SetProofSource(CryptoTestUtils::ProofSourceForTesting());
    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;
  }

  void SetUp() override {
    scoped_ptr<CryptoHandshakeMessage> msg(
        config_.AddDefaultConfig(rand_, &clock_,
        config_options_));

    StringPiece orbit;
    CHECK(msg->GetStringPiece(kORBT, &orbit));
    CHECK_EQ(sizeof(orbit_), orbit.size());
    memcpy(orbit_, orbit.data(), orbit.size());

    char public_value[32];
    memset(public_value, 42, sizeof(public_value));

    const string nonce_str = GenerateNonce();
    nonce_hex_ = "#" + base::HexEncode(nonce_str.data(), nonce_str.size());
    pub_hex_ = "#" + base::HexEncode(public_value, sizeof(public_value));

    CryptoHandshakeMessage client_hello = CryptoTestUtils::Message(
        "CHLO",
        "AEAD", "AESG",
        "KEXS", "C255",
        "PUBS", pub_hex_.c_str(),
        "NONC", nonce_hex_.c_str(),
        "VER\0", client_version_.data(),
        "$padding", static_cast<int>(kClientHelloMinimumSize),
        nullptr);
    ShouldSucceed(client_hello);
    // 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));
    srct_hex_ = "#" + base::HexEncode(srct.data(), srct.size());

    StringPiece scfg;
    ASSERT_TRUE(out_.GetStringPiece(kSCFG, &scfg));
    server_config_.reset(CryptoFramer::ParseMessage(scfg));

    StringPiece scid;
    ASSERT_TRUE(server_config_->GetStringPiece(kSCID, &scid));
    scid_hex_ = "#" + base::HexEncode(scid.data(), scid.size());
  }

  // Helper used to accept the result of ValidateClientHello and pass
  // it on to ProcessClientHello.
  class ValidateCallback : public ValidateClientHelloResultCallback {
   public:
    ValidateCallback(CryptoServerTest* test,
                     bool should_succeed,
                     const char* error_substr,
                     bool* called)
        : test_(test),
          should_succeed_(should_succeed),
          error_substr_(error_substr),
          called_(called) {
      *called_ = false;
    }

    void RunImpl(const CryptoHandshakeMessage& client_hello,
                 const Result& result) override {
      {
        // Ensure that the strike register client lock is not held.
        QuicCryptoServerConfigPeer peer(&test_->config_);
        base::Lock* m = peer.GetStrikeRegisterClientLock();
        // In Chromium, we will dead lock if the lock is held by the current
        // thread. Chromium doesn't have AssertNotHeld API call.
        // m->AssertNotHeld();
        base::AutoLock lock(*m);
      }
      ASSERT_FALSE(*called_);
      test_->ProcessValidationResult(
          client_hello, result, should_succeed_, error_substr_);
      *called_ = true;
    }

   private:
    CryptoServerTest* test_;
    bool should_succeed_;
    const char* error_substr_;
    bool* called_;
  };

  void CheckServerHello(const CryptoHandshakeMessage& server_hello) {
    const QuicTag* versions;
    size_t num_versions;
    server_hello.GetTaglist(kVER, &versions, &num_versions);
    ASSERT_EQ(QuicSupportedVersions().size(), num_versions);
    for (size_t i = 0; i < num_versions; ++i) {
      EXPECT_EQ(QuicVersionToQuicTag(QuicSupportedVersions()[i]), versions[i]);
    }

    StringPiece address;
    ASSERT_TRUE(server_hello.GetStringPiece(kCADR, &address));
    QuicSocketAddressCoder decoder;
    ASSERT_TRUE(decoder.Decode(address.data(), address.size()));
    EXPECT_EQ(client_address_.address(), decoder.ip());
    EXPECT_EQ(client_address_.port(), decoder.port());
  }

  void ShouldSucceed(const CryptoHandshakeMessage& message) {
    bool called = false;
    RunValidate(message, new ValidateCallback(this, true, "", &called));
    EXPECT_TRUE(called);
  }

  void RunValidate(
      const CryptoHandshakeMessage& message,
      ValidateClientHelloResultCallback* cb) {
    config_.ValidateClientHello(message, client_address_, &clock_, cb);
  }

  void ShouldFailMentioning(const char* error_substr,
                            const CryptoHandshakeMessage& message) {
    bool called = false;
    ShouldFailMentioning(error_substr, message, &called);
    EXPECT_TRUE(called);
  }

  void ShouldFailMentioning(const char* error_substr,
                            const CryptoHandshakeMessage& message,
                            bool* called) {
    config_.ValidateClientHello(
        message, client_address_, &clock_,
        new ValidateCallback(this, false, error_substr, called));
  }

  void ProcessValidationResult(const CryptoHandshakeMessage& message,
                               const ValidateCallback::Result& result,
                               bool should_succeed,
                               const char* error_substr) {
    IPEndPoint server_ip;
    string error_details;
    QuicErrorCode error = config_.ProcessClientHello(
        result, 1 /* ConnectionId */, server_ip, client_address_,
        supported_versions_.front(), supported_versions_, &clock_, rand_,
        &params_, &out_, &error_details);

    if (should_succeed) {
      ASSERT_EQ(error, QUIC_NO_ERROR)
          << "Message failed with error " << error_details << ": "
          << message.DebugString();
    } else {
      ASSERT_NE(error, QUIC_NO_ERROR)
          << "Message didn't fail: " << message.DebugString();

      EXPECT_TRUE(error_details.find(error_substr) != string::npos)
          << error_substr << " not in " << error_details;
    }
  }

  CryptoHandshakeMessage InchoateClientHello(const char* message_tag, ...) {
    va_list ap;
    va_start(ap, message_tag);

    CryptoHandshakeMessage message =
        CryptoTestUtils::BuildMessage(message_tag, ap);
    va_end(ap);

    message.SetStringPiece(kPAD, string(kClientHelloMinimumSize, '-'));
    return message;
  }

  string GenerateNonce() {
    string nonce;
    CryptoUtils::GenerateNonce(
        clock_.WallNow(), rand_,
        StringPiece(reinterpret_cast<const char*>(orbit_), sizeof(orbit_)),
        &nonce);
    return nonce;
  }

  void CheckRejectReasons(
      const HandshakeFailureReason* expected_handshake_failures,
      size_t expected_count) {
    const uint32* reject_reasons;
    size_t num_reject_reasons;
    COMPILE_ASSERT(sizeof(QuicTag) == sizeof(uint32), header_out_of_sync);
    QuicErrorCode error_code = out_.GetTaglist(kRREJ, &reject_reasons,
                                               &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_reasons[i]);
    }
  }

 protected:
  QuicRandom* const rand_;
  MockClock clock_;
  const IPEndPoint client_address_;
  QuicVersionVector supported_versions_;
  string client_version_;
  QuicCryptoServerConfig config_;
  QuicCryptoServerConfig::ConfigOptions config_options_;
  QuicCryptoNegotiatedParameters params_;
  CryptoHandshakeMessage out_;
  uint8 orbit_[kOrbitSize];

  // These strings contain hex escaped values from the server suitable for
  // passing to |InchoateClientHello| when constructing client hello messages.
  string nonce_hex_, pub_hex_, srct_hex_, scid_hex_;
  scoped_ptr<CryptoHandshakeMessage> server_config_;
};

// 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",
    "#00",
    "#ff00",
    "127.0.0.1",
    "ffee::1",
  };

  string client_version = QuicUtils::TagToString(
      QuicVersionToQuicTag(supported_versions_.front()));

  for (size_t i = 0; i < arraysize(kBadSNIs); i++) {
    ShouldFailMentioning("SNI", InchoateClientHello(
        "CHLO",
        "SNI", kBadSNIs[i],
        "VER\0", client_version.data(),
        nullptr));
    const HandshakeFailureReason kRejectReasons[] = {
      SERVER_CONFIG_INCHOATE_HELLO_FAILURE
    };
    CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
  }
}

// TODO(rtenneti): Enable the DefaultCert test after implementing ProofSource.
TEST_F(CryptoServerTest, DISABLED_DefaultCert) {
  // Check that the server replies with a default certificate when no SNI is
  // specified.
  ShouldSucceed(InchoateClientHello(
      "CHLO",
      "AEAD", "AESG",
      "KEXS", "C255",
      "SCID", scid_hex_.c_str(),
      "#004b5453", srct_hex_.c_str(),
      "PUBS", pub_hex_.c_str(),
      "NONC", nonce_hex_.c_str(),
      "$padding", static_cast<int>(kClientHelloMinimumSize),
      "PDMD", "X509",
      "VER\0", client_version_.data(),
      nullptr));

  StringPiece cert, proof;
  EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert));
  EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof));
  EXPECT_NE(0u, cert.size());
  EXPECT_NE(0u, proof.size());
  const HandshakeFailureReason kRejectReasons[] = {
    CLIENT_NONCE_INVALID_TIME_FAILURE
  };
  CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}

TEST_P(CryptoServerTest, TooSmall) {
  ShouldFailMentioning("too small", CryptoTestUtils::Message(
        "CHLO",
        "VER\0", client_version_.data(),
        nullptr));
  const HandshakeFailureReason kRejectReasons[] = {
    SERVER_CONFIG_INCHOATE_HELLO_FAILURE
  };
  CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}

TEST_P(CryptoServerTest, BadSourceAddressToken) {
  // Invalid source-address tokens should be ignored.
  static const char* kBadSourceAddressTokens[] = {
    "",
    "foo",
    "#0000",
    "#0000000000000000000000000000000000000000",
  };

  for (size_t i = 0; i < arraysize(kBadSourceAddressTokens); i++) {
    ShouldSucceed(InchoateClientHello(
        "CHLO",
        "STK", kBadSourceAddressTokens[i],
        "VER\0", client_version_.data(),
        nullptr));
    const HandshakeFailureReason kRejectReasons[] = {
      SERVER_CONFIG_INCHOATE_HELLO_FAILURE
    };
    CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
  }
}

TEST_P(CryptoServerTest, BadClientNonce) {
  // Invalid nonces should be ignored.
  static const char* kBadNonces[] = {
    "",
    "#0000",
    "#0000000000000000000000000000000000000000",
  };

  for (size_t i = 0; i < arraysize(kBadNonces); i++) {
    ShouldSucceed(InchoateClientHello(
        "CHLO",
        "NONC", kBadNonces[i],
        "VER\0", client_version_.data(),
        nullptr));
    const HandshakeFailureReason kRejectReasons[] = {
      SERVER_CONFIG_INCHOATE_HELLO_FAILURE
    };
    CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
  }
}

TEST_P(CryptoServerTest, DowngradeAttack) {
  if (supported_versions_.size() == 1) {
    // No downgrade attack is possible if the server only supports one version.
    return;
  }
  // Set the client's preferred version to a supported version that
  // is not the "current" version (supported_versions_.front()).
  string bad_version = QuicUtils::TagToString(
      QuicVersionToQuicTag(supported_versions_.back()));

  ShouldFailMentioning("Downgrade", InchoateClientHello(
      "CHLO",
      "VER\0", bad_version.data(),
      nullptr));
  const HandshakeFailureReason kRejectReasons[] = {
    SERVER_CONFIG_INCHOATE_HELLO_FAILURE
  };
  CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}

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),
      nullptr);
  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),
      nullptr);
  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),
      nullptr);
  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),
      nullptr);
  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",
      "AEAD", "AESG",
      "KEXS", "C255",
      "SCID", 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),
      nullptr);
  ShouldSucceed(msg);
  // The message should be rejected because the strike-register is still
  // quiescent.
  ASSERT_EQ(kREJ, out_.tag());

  const HandshakeFailureReason kRejectReasons[] = {
    CLIENT_NONCE_INVALID_TIME_FAILURE
  };
  CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));

  config_.set_replay_protection(false);

  ShouldSucceed(msg);
  // The message should be accepted now.
  ASSERT_EQ(kSHLO, out_.tag());
  CheckServerHello(out_);

  ShouldSucceed(msg);
  // The message should accepted twice when replay protection is off.
  ASSERT_EQ(kSHLO, out_.tag());
  CheckServerHello(out_);
}

TEST(CryptoServerConfigGenerationTest, Determinism) {
  // Test that using a deterministic PRNG causes the server-config to be
  // deterministic.

  MockRandom rand_a, rand_b;
  const QuicCryptoServerConfig::ConfigOptions options;
  MockClock clock;

  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a);
  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b);
  scoped_ptr<CryptoHandshakeMessage> scfg_a(
      a.AddDefaultConfig(&rand_a, &clock, options));
  scoped_ptr<CryptoHandshakeMessage> scfg_b(
      b.AddDefaultConfig(&rand_b, &clock, options));

  ASSERT_EQ(scfg_a->DebugString(), scfg_b->DebugString());
}

TEST(CryptoServerConfigGenerationTest, SCIDVaries) {
  // This test ensures that the server config ID varies for different server
  // configs.

  MockRandom rand_a, rand_b;
  const QuicCryptoServerConfig::ConfigOptions options;
  MockClock clock;

  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a);
  rand_b.ChangeValue();
  QuicCryptoServerConfig b(QuicCryptoServerConfig::TESTING, &rand_b);
  scoped_ptr<CryptoHandshakeMessage> scfg_a(
      a.AddDefaultConfig(&rand_a, &clock, options));
  scoped_ptr<CryptoHandshakeMessage> scfg_b(
      b.AddDefaultConfig(&rand_b, &clock, options));

  StringPiece scid_a, scid_b;
  EXPECT_TRUE(scfg_a->GetStringPiece(kSCID, &scid_a));
  EXPECT_TRUE(scfg_b->GetStringPiece(kSCID, &scid_b));

  EXPECT_NE(scid_a, scid_b);
}


TEST(CryptoServerConfigGenerationTest, SCIDIsHashOfServerConfig) {
  MockRandom rand_a;
  const QuicCryptoServerConfig::ConfigOptions options;
  MockClock clock;

  QuicCryptoServerConfig a(QuicCryptoServerConfig::TESTING, &rand_a);
  scoped_ptr<CryptoHandshakeMessage> scfg(
      a.AddDefaultConfig(&rand_a, &clock, options));

  StringPiece scid;
  EXPECT_TRUE(scfg->GetStringPiece(kSCID, &scid));
  // Need to take a copy of |scid| has we're about to call |Erase|.
  const string scid_str(scid.as_string());

  scfg->Erase(kSCID);
  scfg->MarkDirty();
  const QuicData& serialized(scfg->GetSerialized());

  scoped_ptr<crypto::SecureHash> hash(
      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
  hash->Update(serialized.data(), serialized.length());
  uint8 digest[16];
  hash->Finish(digest, sizeof(digest));

  ASSERT_EQ(scid.size(), sizeof(digest));
  EXPECT_EQ(0, memcmp(digest, scid_str.data(), sizeof(digest)));
}

class CryptoServerTestNoConfig : public CryptoServerTest {
 public:
  void SetUp() override {
    // Deliberately don't add a config so that we can test this situation.
  }
};

TEST_P(CryptoServerTestNoConfig, DontCrash) {
  ShouldFailMentioning("No config", InchoateClientHello(
      "CHLO",
      "VER\0", client_version_.data(),
      nullptr));

  const HandshakeFailureReason kRejectReasons[] = {
    SERVER_CONFIG_INCHOATE_HELLO_FAILURE
  };
  CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons));
}

class AsyncStrikeServerVerificationTest : public CryptoServerTest {
 protected:
  AsyncStrikeServerVerificationTest() {
  }

  void SetUp() override {
    const string kOrbit = "12345678";
    config_options_.orbit = kOrbit;
    strike_register_client_ = new DelayedVerifyStrikeRegisterClient(
        10000,  // strike_register_max_entries
        static_cast<uint32>(clock_.WallNow().ToUNIXSeconds()),
        60,  // strike_register_window_secs
        reinterpret_cast<const uint8 *>(kOrbit.data()),
        StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
    config_.SetStrikeRegisterClient(strike_register_client_);
    CryptoServerTest::SetUp();
    strike_register_client_->StartDelayingVerification();
  }

  DelayedVerifyStrikeRegisterClient* strike_register_client_;
};

TEST_P(AsyncStrikeServerVerificationTest, AsyncReplayProtection) {
  // This tests async validation with a strike register works.
  CryptoHandshakeMessage msg = CryptoTestUtils::Message(
      "CHLO",
      "AEAD", "AESG",
      "KEXS", "C255",
      "SCID", 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),
      nullptr);

  // Clear the message tag.
  out_.set_tag(0);

  bool called = false;
  RunValidate(msg, new ValidateCallback(this, true, "", &called));
  // The verification request was queued.
  ASSERT_FALSE(called);
  EXPECT_EQ(0u, out_.tag());
  EXPECT_EQ(1, strike_register_client_->PendingVerifications());

  // Continue processing the verification request.
  strike_register_client_->RunPendingVerifications();
  ASSERT_TRUE(called);
  EXPECT_EQ(0, strike_register_client_->PendingVerifications());
  // The message should be accepted now.
  EXPECT_EQ(kSHLO, out_.tag());

  // Rejected if replayed.
  RunValidate(msg, new ValidateCallback(this, true, "", &called));
  // The verification request was queued.
  ASSERT_FALSE(called);
  EXPECT_EQ(1, strike_register_client_->PendingVerifications());

  strike_register_client_->RunPendingVerifications();
  ASSERT_TRUE(called);
  EXPECT_EQ(0, strike_register_client_->PendingVerifications());
  // The message should be rejected now.
  EXPECT_EQ(kREJ, out_.tag());
}

}  // namespace test
}  // namespace net
