blob: 689458b71c27d8ea2330abfc3c776a72f9fd2ccf [file] [log] [blame]
[email protected]08b14a52012-07-02 23:30:361// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]c6e584c2011-05-18 11:58:442// 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"
[email protected]3fc40c142011-12-01 13:09:0410#include "base/message_loop.h"
[email protected]c6e584c2011-05-18 11:58:4411#include "base/time.h"
[email protected]e97882f2012-06-04 02:23:1712#include "content/public/test/test_browser_thread.h"
[email protected]c6e584c2011-05-18 11:58:4413#include "testing/gtest/include/gtest/gtest.h"
14
[email protected]08b14a52012-07-02 23:30:3615namespace chrome {
[email protected]c6e584c2011-05-18 11:58:4416
17class InternalAuthTest : public ::testing::Test {
18 public:
19 InternalAuthTest() {
20 long_string_ = "seed";
21 for (int i = 20; i--;)
22 long_string_ += long_string_;
23 }
24 virtual ~InternalAuthTest() {}
25
26 virtual void SetUp() {
27 }
28
29 virtual void TearDown() {
30 }
31
32 MessageLoop message_loop_;
33 std::string long_string_;
34};
35
36TEST_F(InternalAuthTest, BasicGeneration) {
37 std::map<std::string, std::string> map;
38 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:3639 std::string token = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4440 "zapata", map);
41 ASSERT_GT(token.size(), 10u); // short token is insecure.
42
43 map["key2"] = "value2";
[email protected]08b14a52012-07-02 23:30:3644 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:4445 ASSERT_GT(token.size(), 10u);
46}
47
48TEST_F(InternalAuthTest, DoubleGeneration) {
49 std::map<std::string, std::string> map;
50 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:3651 std::string token1 = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4452 "zapata", map);
53 ASSERT_GT(token1.size(), 10u);
54
[email protected]08b14a52012-07-02 23:30:3655 std::string token2 = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4456 "zapata", map);
57 ASSERT_GT(token2.size(), 10u);
58 // tokens are different even if credentials coincide.
59 ASSERT_NE(token1, token2);
60}
61
62TEST_F(InternalAuthTest, BadGeneration) {
63 std::map<std::string, std::string> map;
64 map["key"] = "value";
65 // Trying huge domain.
[email protected]08b14a52012-07-02 23:30:3666 std::string token = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4467 long_string_, map);
68 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3669 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:4470 token, long_string_, map));
71
72 // Trying empty domain.
[email protected]08b14a52012-07-02 23:30:3673 token = InternalAuthGeneration::GeneratePassport("", map);
[email protected]c6e584c2011-05-18 11:58:4474 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3675 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "", map));
[email protected]c6e584c2011-05-18 11:58:4476
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.
[email protected]08b14a52012-07-02 23:30:3686 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:4487 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3688 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:4489
90 map.clear();
91 map[""] = "value";
92 // Trying empty key.
[email protected]08b14a52012-07-02 23:30:3693 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:4494 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3695 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:4496}
97
98TEST_F(InternalAuthTest, BasicVerification) {
99 std::map<std::string, std::string> map;
100 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36101 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44102 ASSERT_GT(token.size(), 10u);
[email protected]08b14a52012-07-02 23:30:36103 ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44104 // Passport can not be reused.
[email protected]8212d2c2011-05-19 11:01:19105 for (int i = 1000; i--;) {
[email protected]08b14a52012-07-02 23:30:36106 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44107 token, "zapata", map));
108 }
109}
110
111TEST_F(InternalAuthTest, BruteForce) {
112 std::map<std::string, std::string> map;
113 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36114 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44115 ASSERT_GT(token.size(), 10u);
116
117 // Trying bruteforce.
118 std::string dummy = token;
[email protected]8212d2c2011-05-19 11:01:19119 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44120 std::next_permutation(dummy.begin(), dummy.end());
[email protected]08b14a52012-07-02 23:30:36121 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44122 dummy, "zapata", map));
123 }
124 dummy = token;
[email protected]8212d2c2011-05-19 11:01:19125 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44126 std::next_permutation(dummy.begin(), dummy.begin() + dummy.size() / 2);
[email protected]08b14a52012-07-02 23:30:36127 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44128 dummy, "zapata", map));
129 }
130 // We brute forced just too little, so original token must not expire yet.
[email protected]08b14a52012-07-02 23:30:36131 ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44132}
133
134TEST_F(InternalAuthTest, ExpirationAndBruteForce) {
135 int kCustomVerificationWindow = 2;
[email protected]08b14a52012-07-02 23:30:36136 InternalAuthVerification::set_verification_window_seconds(
[email protected]c6e584c2011-05-18 11:58:44137 kCustomVerificationWindow);
138
139 std::map<std::string, std::string> map;
140 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36141 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44142 ASSERT_GT(token.size(), 10u);
143
144 // We want to test token expiration, so we need to wait some amount of time,
145 // so we are brute-forcing during this time.
146 base::Time timestamp = base::Time::Now();
147 std::string dummy1 = token;
148 std::string dummy2 = token;
149 for (;;) {
[email protected]8212d2c2011-05-19 11:01:19150 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44151 std::next_permutation(dummy1.begin(), dummy1.end());
[email protected]08b14a52012-07-02 23:30:36152 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44153 dummy1, "zapata", map));
154 }
[email protected]8212d2c2011-05-19 11:01:19155 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44156 std::next_permutation(dummy2.begin(), dummy2.begin() + dummy2.size() / 2);
[email protected]08b14a52012-07-02 23:30:36157 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44158 dummy2, "zapata", map));
159 }
160 if (base::Time::Now() - timestamp > base::TimeDelta::FromSeconds(
161 kCustomVerificationWindow + 1)) {
162 break;
163 }
164 }
[email protected]08b14a52012-07-02 23:30:36165 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44166 // Reset verification window to default.
[email protected]08b14a52012-07-02 23:30:36167 InternalAuthVerification::set_verification_window_seconds(0);
[email protected]c6e584c2011-05-18 11:58:44168}
169
170TEST_F(InternalAuthTest, ChangeKey) {
171 std::map<std::string, std::string> map;
172 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36173 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44174 ASSERT_GT(token.size(), 10u);
175
[email protected]08b14a52012-07-02 23:30:36176 InternalAuthGeneration::GenerateNewKey();
[email protected]c6e584c2011-05-18 11:58:44177 // Passport should survive key change.
[email protected]08b14a52012-07-02 23:30:36178 ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44179
[email protected]08b14a52012-07-02 23:30:36180 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44181 ASSERT_GT(token.size(), 10u);
182 for (int i = 20; i--;)
[email protected]08b14a52012-07-02 23:30:36183 InternalAuthGeneration::GenerateNewKey();
[email protected]c6e584c2011-05-18 11:58:44184 // Passport should not survive series of key changes.
[email protected]08b14a52012-07-02 23:30:36185 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44186}
187
[email protected]08b14a52012-07-02 23:30:36188} // namespace chrome