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/local_strike_register_client.h"
6
7#include <memory>
8
9#include "base/memory/scoped_ptr.h"
10#include "base/strings/string_piece.h"
11#include "base/sys_byteorder.h"
12#include "net/quic/crypto/crypto_protocol.h"
13#include "net/quic/quic_time.h"
14#include "testing/gtest/include/gtest/gtest.h"
15
16using base::StringPiece;
17using std::string;
18
19namespace net {
20namespace test {
21namespace {
22
23class RecordResultCallback : public StrikeRegisterClient::ResultCallback {
24 public:
25  // RecordResultCallback stores the argument to RunImpl in
26  // |*saved_value| and sets |*called| to true.  The callback is self
27  // deleting.
28  RecordResultCallback(bool* called, bool* saved_value)
29      : called_(called),
30        saved_value_(saved_value) {
31    *called_ = false;
32  }
33
34 protected:
35  virtual void RunImpl(bool nonce_is_valid_and_unique) OVERRIDE {
36    *called_ = true;
37    *saved_value_ = nonce_is_valid_and_unique;
38  }
39
40 private:
41  bool* called_;
42  bool* saved_value_;
43
44  DISALLOW_COPY_AND_ASSIGN(RecordResultCallback);
45};
46
47const uint8 kOrbit[] = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0";
48const uint32 kCurrentTimeExternalSecs = 12345678;
49size_t kMaxEntries = 100;
50uint32 kWindowSecs = 60;
51
52class LocalStrikeRegisterClientTest : public ::testing::Test {
53 protected:
54  LocalStrikeRegisterClientTest() {
55  }
56
57  virtual void SetUp() {
58    strike_register_.reset(new LocalStrikeRegisterClient(
59        kMaxEntries, kCurrentTimeExternalSecs, kWindowSecs, kOrbit,
60        net::StrikeRegister::NO_STARTUP_PERIOD_NEEDED));
61  }
62
63  scoped_ptr<LocalStrikeRegisterClient> strike_register_;
64};
65
66TEST_F(LocalStrikeRegisterClientTest, CheckOrbit) {
67  EXPECT_TRUE(strike_register_->IsKnownOrbit(
68      StringPiece(reinterpret_cast<const char*>(kOrbit), kOrbitSize)));
69  EXPECT_FALSE(strike_register_->IsKnownOrbit(
70      StringPiece(reinterpret_cast<const char*>(kOrbit), kOrbitSize - 1)));
71  EXPECT_FALSE(strike_register_->IsKnownOrbit(
72      StringPiece(reinterpret_cast<const char*>(kOrbit), kOrbitSize + 1)));
73  EXPECT_FALSE(strike_register_->IsKnownOrbit(
74      StringPiece(reinterpret_cast<const char*>(kOrbit) + 1, kOrbitSize)));
75}
76
77TEST_F(LocalStrikeRegisterClientTest, IncorrectNonceLength) {
78  string valid_nonce;
79  uint32 norder = htonl(kCurrentTimeExternalSecs);
80  valid_nonce.assign(reinterpret_cast<const char*>(&norder), sizeof(norder));
81  valid_nonce.append(string(reinterpret_cast<const char*>(kOrbit), kOrbitSize));
82  valid_nonce.append(string(20, '\x17'));  // 20 'random' bytes.
83
84  {
85    // Validation fails if you remove a byte from the nonce.
86    bool called;
87    bool is_valid;
88    string short_nonce = valid_nonce.substr(0, valid_nonce.length() - 1);
89    strike_register_->VerifyNonceIsValidAndUnique(
90        short_nonce,
91        QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
92        new RecordResultCallback(&called, &is_valid));
93    EXPECT_TRUE(called);
94    EXPECT_FALSE(is_valid);
95  }
96
97  {
98    // Validation fails if you add a byte to the nonce.
99    bool called;
100    bool is_valid;
101    string long_nonce(valid_nonce);
102    long_nonce.append("a");
103    strike_register_->VerifyNonceIsValidAndUnique(
104        long_nonce,
105        QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
106        new RecordResultCallback(&called, &is_valid));
107    EXPECT_TRUE(called);
108    EXPECT_FALSE(is_valid);
109  }
110
111  {
112    // Verify that the base nonce validates was valid.
113    bool called;
114    bool is_valid;
115    strike_register_->VerifyNonceIsValidAndUnique(
116        valid_nonce,
117        QuicWallTime::FromUNIXSeconds(kCurrentTimeExternalSecs),
118        new RecordResultCallback(&called, &is_valid));
119    EXPECT_TRUE(called);
120    EXPECT_TRUE(is_valid);
121  }
122}
123
124}  // namespace
125}  // namespace test
126}  // namespace net
127