blob: 450992e18cdf6aaca6669a3e0efd222e6d454b21 [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
avi6846aef2015-12-26 01:09:387#include <stddef.h>
8
[email protected]c6e584c2011-05-18 11:58:449#include <algorithm>
10
11#include "base/lazy_instance.h"
[email protected]467a106e2013-07-18 12:07:1912#include "base/message_loop/message_loop.h"
[email protected]0e498482013-06-28 01:53:4313#include "base/time/time.h"
[email protected]c6e584c2011-05-18 11:58:4414#include "testing/gtest/include/gtest/gtest.h"
15
[email protected]c6e584c2011-05-18 11:58:4416class InternalAuthTest : public ::testing::Test {
17 public:
18 InternalAuthTest() {
19 long_string_ = "seed";
20 for (int i = 20; i--;)
21 long_string_ += long_string_;
22 }
dchenge1bc7982014-10-30 00:32:4023 ~InternalAuthTest() override {}
[email protected]c6e584c2011-05-18 11:58:4424
dchenge1bc7982014-10-30 00:32:4025 void SetUp() override {}
[email protected]c6e584c2011-05-18 11:58:4426
dchenge1bc7982014-10-30 00:32:4027 void TearDown() override {}
[email protected]c6e584c2011-05-18 11:58:4428
[email protected]b3a25092013-05-28 22:08:1629 base::MessageLoop message_loop_;
[email protected]c6e584c2011-05-18 11:58:4430 std::string long_string_;
31};
32
33TEST_F(InternalAuthTest, BasicGeneration) {
34 std::map<std::string, std::string> map;
35 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:3636 std::string token = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4437 "zapata", map);
38 ASSERT_GT(token.size(), 10u); // short token is insecure.
39
40 map["key2"] = "value2";
[email protected]08b14a52012-07-02 23:30:3641 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:4442 ASSERT_GT(token.size(), 10u);
43}
44
45TEST_F(InternalAuthTest, DoubleGeneration) {
46 std::map<std::string, std::string> map;
47 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:3648 std::string token1 = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4449 "zapata", map);
50 ASSERT_GT(token1.size(), 10u);
51
[email protected]08b14a52012-07-02 23:30:3652 std::string token2 = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4453 "zapata", map);
54 ASSERT_GT(token2.size(), 10u);
55 // tokens are different even if credentials coincide.
56 ASSERT_NE(token1, token2);
57}
58
59TEST_F(InternalAuthTest, BadGeneration) {
60 std::map<std::string, std::string> map;
61 map["key"] = "value";
62 // Trying huge domain.
[email protected]08b14a52012-07-02 23:30:3663 std::string token = InternalAuthGeneration::GeneratePassport(
[email protected]c6e584c2011-05-18 11:58:4464 long_string_, map);
65 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3666 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:4467 token, long_string_, map));
68
69 // Trying empty domain.
[email protected]007b3f82013-04-09 08:46:4570 token = InternalAuthGeneration::GeneratePassport(std::string(), map);
[email protected]c6e584c2011-05-18 11:58:4471 ASSERT_TRUE(token.empty());
[email protected]007b3f82013-04-09 08:46:4572 ASSERT_FALSE(
73 InternalAuthVerification::VerifyPassport(token, std::string(), map));
[email protected]c6e584c2011-05-18 11:58:4474
75 std::string dummy("abcdefghij");
76 for (size_t i = 1000; i--;) {
77 std::string key = dummy;
78 std::next_permutation(dummy.begin(), dummy.end());
79 std::string value = dummy;
80 std::next_permutation(dummy.begin(), dummy.end());
81 map[key] = value;
82 }
83 // Trying huge var=value map.
[email protected]08b14a52012-07-02 23:30:3684 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:4485 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3686 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:4487
88 map.clear();
[email protected]007b3f82013-04-09 08:46:4589 map[std::string()] = "value";
[email protected]c6e584c2011-05-18 11:58:4490 // Trying empty key.
[email protected]08b14a52012-07-02 23:30:3691 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:4492 ASSERT_TRUE(token.empty());
[email protected]08b14a52012-07-02 23:30:3693 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:4494}
95
96TEST_F(InternalAuthTest, BasicVerification) {
97 std::map<std::string, std::string> map;
98 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:3699 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44100 ASSERT_GT(token.size(), 10u);
[email protected]08b14a52012-07-02 23:30:36101 ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44102 // Passport can not be reused.
[email protected]8212d2c2011-05-19 11:01:19103 for (int i = 1000; i--;) {
[email protected]08b14a52012-07-02 23:30:36104 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44105 token, "zapata", map));
106 }
107}
108
109TEST_F(InternalAuthTest, BruteForce) {
110 std::map<std::string, std::string> map;
111 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36112 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44113 ASSERT_GT(token.size(), 10u);
114
115 // Trying bruteforce.
116 std::string dummy = token;
[email protected]8212d2c2011-05-19 11:01:19117 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44118 std::next_permutation(dummy.begin(), dummy.end());
[email protected]08b14a52012-07-02 23:30:36119 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44120 dummy, "zapata", map));
121 }
122 dummy = token;
[email protected]8212d2c2011-05-19 11:01:19123 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44124 std::next_permutation(dummy.begin(), dummy.begin() + dummy.size() / 2);
[email protected]08b14a52012-07-02 23:30:36125 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44126 dummy, "zapata", map));
127 }
128 // We brute forced just too little, so original token must not expire yet.
[email protected]08b14a52012-07-02 23:30:36129 ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44130}
131
132TEST_F(InternalAuthTest, ExpirationAndBruteForce) {
133 int kCustomVerificationWindow = 2;
[email protected]08b14a52012-07-02 23:30:36134 InternalAuthVerification::set_verification_window_seconds(
[email protected]c6e584c2011-05-18 11:58:44135 kCustomVerificationWindow);
136
137 std::map<std::string, std::string> map;
138 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36139 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44140 ASSERT_GT(token.size(), 10u);
141
142 // We want to test token expiration, so we need to wait some amount of time,
143 // so we are brute-forcing during this time.
144 base::Time timestamp = base::Time::Now();
145 std::string dummy1 = token;
146 std::string dummy2 = token;
147 for (;;) {
[email protected]8212d2c2011-05-19 11:01:19148 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44149 std::next_permutation(dummy1.begin(), dummy1.end());
[email protected]08b14a52012-07-02 23:30:36150 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44151 dummy1, "zapata", map));
152 }
[email protected]8212d2c2011-05-19 11:01:19153 for (size_t i = 100; i--;) {
[email protected]c6e584c2011-05-18 11:58:44154 std::next_permutation(dummy2.begin(), dummy2.begin() + dummy2.size() / 2);
[email protected]08b14a52012-07-02 23:30:36155 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(
[email protected]c6e584c2011-05-18 11:58:44156 dummy2, "zapata", map));
157 }
158 if (base::Time::Now() - timestamp > base::TimeDelta::FromSeconds(
159 kCustomVerificationWindow + 1)) {
160 break;
161 }
162 }
[email protected]08b14a52012-07-02 23:30:36163 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44164 // Reset verification window to default.
[email protected]08b14a52012-07-02 23:30:36165 InternalAuthVerification::set_verification_window_seconds(0);
[email protected]c6e584c2011-05-18 11:58:44166}
167
168TEST_F(InternalAuthTest, ChangeKey) {
169 std::map<std::string, std::string> map;
170 map["key"] = "value";
[email protected]08b14a52012-07-02 23:30:36171 std::string token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44172 ASSERT_GT(token.size(), 10u);
173
[email protected]08b14a52012-07-02 23:30:36174 InternalAuthGeneration::GenerateNewKey();
[email protected]c6e584c2011-05-18 11:58:44175 // Passport should survive key change.
[email protected]08b14a52012-07-02 23:30:36176 ASSERT_TRUE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44177
[email protected]08b14a52012-07-02 23:30:36178 token = InternalAuthGeneration::GeneratePassport("zapata", map);
[email protected]c6e584c2011-05-18 11:58:44179 ASSERT_GT(token.size(), 10u);
180 for (int i = 20; i--;)
[email protected]08b14a52012-07-02 23:30:36181 InternalAuthGeneration::GenerateNewKey();
[email protected]c6e584c2011-05-18 11:58:44182 // Passport should not survive series of key changes.
[email protected]08b14a52012-07-02 23:30:36183 ASSERT_FALSE(InternalAuthVerification::VerifyPassport(token, "zapata", map));
[email protected]c6e584c2011-05-18 11:58:44184}