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