blob: 7ee68ebecf7e3a8e4b417dc1aefa264c0e7e658e [file] [log] [blame]
[email protected]c6e584c2011-05-18 11:58:441// Copyright (c) 2011 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 "chrome/browser/internal_auth.h"
6
7#include <algorithm>
8
9#include "base/lazy_instance.h"
10#include "base/time.h"
11#include "content/browser/browser_thread.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14namespace browser {
15
16class InternalAuthTest : public ::testing::Test {
17 public:
18 InternalAuthTest() {
19 long_string_ = "seed";
20 for (int i = 20; i--;)
21 long_string_ += long_string_;
22 }
23 virtual ~InternalAuthTest() {}
24
25 virtual void SetUp() {
26 }
27
28 virtual void TearDown() {
29 }
30
31 MessageLoop message_loop_;
32 std::string long_string_;
33};
34
35TEST_F(InternalAuthTest, BasicGeneration) {
36 std::map<std::string, std::string> map;
37 map["key"] = "value";
38 std::string token = browser::InternalAuthGeneration::GeneratePassport(
39 "zapata", map);
40 ASSERT_GT(token.size(), 10u); // short token is insecure.
41
42 map["key2"] = "value2";
43 token = browser::InternalAuthGeneration::GeneratePassport("zapata", map);
44 ASSERT_GT(token.size(), 10u);
45}
46
47TEST_F(InternalAuthTest, DoubleGeneration) {
48 std::map<std::string, std::string> map;
49 map["key"] = "value";
50 std::string token1 = browser::InternalAuthGeneration::GeneratePassport(
51 "zapata", map);
52 ASSERT_GT(token1.size(), 10u);
53
54 std::string token2 = browser::InternalAuthGeneration::GeneratePassport(
55 "zapata", map);
56 ASSERT_GT(token2.size(), 10u);
57 // tokens are different even if credentials coincide.
58 ASSERT_NE(token1, token2);
59}
60
61TEST_F(InternalAuthTest, BadGeneration) {
62 std::map<std::string, std::string> map;
63 map["key"] = "value";
64 // Trying huge domain.
65 std::string token = browser::InternalAuthGeneration::GeneratePassport(
66 long_string_, map);
67 ASSERT_TRUE(token.empty());
68 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
69 token, long_string_, map));
70
71 // Trying empty domain.
72 token = browser::InternalAuthGeneration::GeneratePassport("", map);
73 ASSERT_TRUE(token.empty());
74 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
75 token, "", map));
76
77 std::string dummy("abcdefghij");
78 for (size_t i = 1000; i--;) {
79 std::string key = dummy;
80 std::next_permutation(dummy.begin(), dummy.end());
81 std::string value = dummy;
82 std::next_permutation(dummy.begin(), dummy.end());
83 map[key] = value;
84 }
85 // Trying huge var=value map.
86 token = browser::InternalAuthGeneration::GeneratePassport("zapata", map);
87 ASSERT_TRUE(token.empty());
88 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
89 token, "zapata", map));
90
91 map.clear();
92 map[""] = "value";
93 // Trying empty key.
94 token = browser::InternalAuthGeneration::GeneratePassport("zapata", map);
95 ASSERT_TRUE(token.empty());
96 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
97 token, "zapata", map));
98}
99
100TEST_F(InternalAuthTest, BasicVerification) {
101 std::map<std::string, std::string> map;
102 map["key"] = "value";
103 std::string token = browser::InternalAuthGeneration::GeneratePassport(
104 "zapata", map);
105 ASSERT_GT(token.size(), 10u);
106 ASSERT_TRUE(browser::InternalAuthVerification::VerifyPassport(
107 token, "zapata", map));
108 // Passport can not be reused.
[email protected]8212d2c2011-05-19 11:01:19109 for (int i = 1000; i--;) {
[email protected]c6e584c2011-05-18 11:58:44110 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
111 token, "zapata", map));
112 }
113}
114
115TEST_F(InternalAuthTest, BruteForce) {
116 std::map<std::string, std::string> map;
117 map["key"] = "value";
118 std::string token = browser::InternalAuthGeneration::GeneratePassport(
119 "zapata", map);
120 ASSERT_GT(token.size(), 10u);
121
122 // Trying bruteforce.
123 std::string dummy = token;
[email protected]8212d2c2011-05-19 11:01:19124 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44125 std::next_permutation(dummy.begin(), dummy.end());
126 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
127 dummy, "zapata", map));
128 }
129 dummy = token;
[email protected]8212d2c2011-05-19 11:01:19130 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44131 std::next_permutation(dummy.begin(), dummy.begin() + dummy.size() / 2);
132 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
133 dummy, "zapata", map));
134 }
135 // We brute forced just too little, so original token must not expire yet.
136 ASSERT_TRUE(browser::InternalAuthVerification::VerifyPassport(
137 token, "zapata", map));
138}
139
140TEST_F(InternalAuthTest, ExpirationAndBruteForce) {
141 int kCustomVerificationWindow = 2;
142 browser::InternalAuthVerification::set_verification_window_seconds(
143 kCustomVerificationWindow);
144
145 std::map<std::string, std::string> map;
146 map["key"] = "value";
147 std::string token = browser::InternalAuthGeneration::GeneratePassport(
148 "zapata", map);
149 ASSERT_GT(token.size(), 10u);
150
151 // We want to test token expiration, so we need to wait some amount of time,
152 // so we are brute-forcing during this time.
153 base::Time timestamp = base::Time::Now();
154 std::string dummy1 = token;
155 std::string dummy2 = token;
156 for (;;) {
[email protected]8212d2c2011-05-19 11:01:19157 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44158 std::next_permutation(dummy1.begin(), dummy1.end());
159 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
160 dummy1, "zapata", map));
161 }
[email protected]8212d2c2011-05-19 11:01:19162 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44163 std::next_permutation(dummy2.begin(), dummy2.begin() + dummy2.size() / 2);
164 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
165 dummy2, "zapata", map));
166 }
167 if (base::Time::Now() - timestamp > base::TimeDelta::FromSeconds(
168 kCustomVerificationWindow + 1)) {
169 break;
170 }
171 }
172 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
173 token, "zapata", map));
174 // Reset verification window to default.
175 browser::InternalAuthVerification::set_verification_window_seconds(0);
176}
177
178TEST_F(InternalAuthTest, ChangeKey) {
179 std::map<std::string, std::string> map;
180 map["key"] = "value";
181 std::string token = browser::InternalAuthGeneration::GeneratePassport(
182 "zapata", map);
183 ASSERT_GT(token.size(), 10u);
184
185 browser::InternalAuthGeneration::GenerateNewKey();
186 // Passport should survive key change.
187 ASSERT_TRUE(browser::InternalAuthVerification::VerifyPassport(
188 token, "zapata", map));
189
190 token = browser::InternalAuthGeneration::GeneratePassport("zapata", map);
191 ASSERT_GT(token.size(), 10u);
192 for (int i = 20; i--;)
193 browser::InternalAuthGeneration::GenerateNewKey();
194 // Passport should not survive series of key changes.
195 ASSERT_FALSE(browser::InternalAuthVerification::VerifyPassport(
196 token, "zapata", map));
197}
198
199} // namespace browser