1 // Copyright 2015 The Weave 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 "src/privet/auth_manager.h"
6 
7 #include <gmock/gmock.h>
8 #include <gtest/gtest.h>
9 #include <weave/settings.h>
10 
11 #include "src/config.h"
12 #include "src/data_encoding.h"
13 #include "src/privet/mock_delegates.h"
14 #include "src/test/mock_clock.h"
15 
16 using testing::Return;
17 
18 namespace weave {
19 namespace privet {
20 
21 class AuthManagerTest : public testing::Test {
22  public:
SetUp()23   void SetUp() override {
24     EXPECT_GE(auth_.GetAuthSecret().size(), 32u);
25     EXPECT_GE(auth_.GetAccessSecret().size(), 32u);
26     EXPECT_GE(auth_.GetCertificateFingerprint().size(), 32u);
27 
28     EXPECT_CALL(clock_, Now())
29         .WillRepeatedly(Return(base::Time::FromTimeT(1410000000)));
30   }
31 
32  protected:
DelegateToUser(const std::vector<uint8_t> & token,base::TimeDelta ttl,const UserInfo & user_info) const33   std::vector<uint8_t> DelegateToUser(const std::vector<uint8_t>& token,
34                                       base::TimeDelta ttl,
35                                       const UserInfo& user_info) const {
36     return auth_.DelegateToUser(token, ttl, user_info);
37   }
38   const std::vector<uint8_t> kSecret1{
39       78, 40, 39, 68, 29, 19, 70, 86, 38, 61, 13, 55, 33, 32, 51, 52,
40       34, 43, 97, 48, 8,  56, 11, 99, 50, 59, 24, 26, 31, 71, 76, 28};
41   const std::vector<uint8_t> kSecret2{
42       69, 53, 17, 37, 80, 73, 2,  5, 79, 64, 41, 57, 12, 54, 65, 63,
43       72, 74, 93, 81, 20, 95, 89, 3, 94, 92, 27, 21, 49, 90, 36, 6};
44   const std::vector<uint8_t> kFingerprint{
45       22, 47, 23, 77, 42, 98, 96, 25,  83, 16, 9, 14, 91, 44, 15, 75,
46       60, 62, 10, 18, 82, 35, 88, 100, 30, 45, 7, 46, 67, 84, 58, 85};
47 
48   test::MockClock clock_;
49   AuthManager auth_{kSecret1, kFingerprint, kSecret2, &clock_};
50 };
51 
TEST_F(AuthManagerTest,RandomSecret)52 TEST_F(AuthManagerTest, RandomSecret) {
53   AuthManager auth{{}, {}, {}, &clock_};
54   EXPECT_EQ(auth.GetAuthSecret().size(), 32u);
55   EXPECT_EQ(auth.GetAccessSecret().size(), 32u);
56 }
57 
TEST_F(AuthManagerTest,DifferentSecret)58 TEST_F(AuthManagerTest, DifferentSecret) {
59   AuthManager auth{kSecret2, {}, kSecret1};
60   EXPECT_EQ(auth.GetAuthSecret().size(), 32u);
61   EXPECT_EQ(auth.GetAccessSecret().size(), 32u);
62   EXPECT_NE(auth_.GetAccessSecret(), auth.GetAccessSecret());
63   EXPECT_NE(auth_.GetAuthSecret(), auth.GetAuthSecret());
64 }
65 
TEST_F(AuthManagerTest,Constructor)66 TEST_F(AuthManagerTest, Constructor) {
67   EXPECT_EQ(kSecret1, auth_.GetAuthSecret());
68   EXPECT_EQ(kSecret2, auth_.GetAccessSecret());
69   EXPECT_EQ(kFingerprint, auth_.GetCertificateFingerprint());
70 }
71 
TEST_F(AuthManagerTest,CreateAccessToken)72 TEST_F(AuthManagerTest, CreateAccessToken) {
73   EXPECT_EQ("WC2FRggaG52hAEIBFEYJRDIzNABCCkBGBRobnaEAUFAF46oQlMmXgnLstt7wU2w=",
74             Base64Encode(auth_.CreateAccessToken(
75                 UserInfo{AuthScope::kViewer, TestUserId{"234"}}, {})));
76   EXPECT_EQ("WC2FRggaG52hAEIBCEYJRDI1NwBCCkBGBRobnaEAUEdWRNHcu/0mA6c3e0tgDrk=",
77             Base64Encode(auth_.CreateAccessToken(
78                 UserInfo{AuthScope::kManager, TestUserId{"257"}}, {})));
79   EXPECT_EQ("WC2FRggaG52hAEIBAkYJRDQ1NgBCCkBGBRobnaEAUH2ZLgUPdTtjNRa+PoDkMW4=",
80             Base64Encode(auth_.CreateAccessToken(
81                 UserInfo{AuthScope::kOwner, TestUserId{"456"}}, {})));
82   auto new_time = clock_.Now() + base::TimeDelta::FromDays(11);
83   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
84   EXPECT_EQ("WC2FRggaG6whgEIBDkYJRDM0NQBCCkBGBRobrCGAUDAFptj7bbYmbpaa6Wpb1Wo=",
85             Base64Encode(auth_.CreateAccessToken(
86                 UserInfo{AuthScope::kUser, TestUserId{"345"}}, {})));
87 }
88 
TEST_F(AuthManagerTest,CreateSameToken)89 TEST_F(AuthManagerTest, CreateSameToken) {
90   EXPECT_EQ(auth_.CreateAccessToken(
91                 UserInfo{AuthScope::kViewer, TestUserId{"555"}}, {}),
92             auth_.CreateAccessToken(
93                 UserInfo{AuthScope::kViewer, TestUserId{"555"}}, {}));
94 }
95 
TEST_F(AuthManagerTest,CreateSameTokenWithApp)96 TEST_F(AuthManagerTest, CreateSameTokenWithApp) {
97   EXPECT_EQ(auth_.CreateAccessToken(
98                 UserInfo{AuthScope::kViewer,
99                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
100                 {}),
101             auth_.CreateAccessToken(
102                 UserInfo{AuthScope::kViewer,
103                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
104                 {}));
105 }
106 
TEST_F(AuthManagerTest,CreateSameTokenWithDifferentType)107 TEST_F(AuthManagerTest, CreateSameTokenWithDifferentType) {
108   EXPECT_NE(auth_.CreateAccessToken(
109                 UserInfo{AuthScope::kViewer,
110                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
111                 {}),
112             auth_.CreateAccessToken(
113                 UserInfo{AuthScope::kViewer,
114                          {AuthType::kPairing, {1, 2, 3}, {4, 5, 6}}},
115                 {}));
116 }
117 
TEST_F(AuthManagerTest,CreateSameTokenWithDifferentApp)118 TEST_F(AuthManagerTest, CreateSameTokenWithDifferentApp) {
119   EXPECT_NE(auth_.CreateAccessToken(
120                 UserInfo{AuthScope::kViewer,
121                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
122                 {}),
123             auth_.CreateAccessToken(
124                 UserInfo{AuthScope::kViewer,
125                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 7}}},
126                 {}));
127 }
128 
TEST_F(AuthManagerTest,CreateTokenDifferentScope)129 TEST_F(AuthManagerTest, CreateTokenDifferentScope) {
130   EXPECT_NE(auth_.CreateAccessToken(
131                 UserInfo{AuthScope::kViewer, TestUserId{"456"}}, {}),
132             auth_.CreateAccessToken(
133                 UserInfo{AuthScope::kOwner, TestUserId{"456"}}, {}));
134 }
135 
TEST_F(AuthManagerTest,CreateTokenDifferentUser)136 TEST_F(AuthManagerTest, CreateTokenDifferentUser) {
137   EXPECT_NE(auth_.CreateAccessToken(
138                 UserInfo{AuthScope::kOwner, TestUserId{"456"}}, {}),
139             auth_.CreateAccessToken(
140                 UserInfo{AuthScope::kOwner, TestUserId{"789"}}, {}));
141 }
142 
TEST_F(AuthManagerTest,CreateTokenDifferentTime)143 TEST_F(AuthManagerTest, CreateTokenDifferentTime) {
144   auto token = auth_.CreateAccessToken(
145       UserInfo{AuthScope::kOwner, TestUserId{"567"}}, {});
146   EXPECT_CALL(clock_, Now())
147       .WillRepeatedly(Return(base::Time::FromTimeT(1400000000)));
148   EXPECT_NE(token, auth_.CreateAccessToken(
149                        UserInfo{AuthScope::kOwner, TestUserId{"567"}}, {}));
150 }
151 
TEST_F(AuthManagerTest,CreateTokenDifferentInstance)152 TEST_F(AuthManagerTest, CreateTokenDifferentInstance) {
153   EXPECT_NE(auth_.CreateAccessToken(
154                 UserInfo{AuthScope::kUser, TestUserId{"123"}}, {}),
155             AuthManager({}, {}).CreateAccessToken(
156                 UserInfo{AuthScope::kUser, TestUserId{"123"}}, {}));
157 }
158 
TEST_F(AuthManagerTest,ParseAccessToken)159 TEST_F(AuthManagerTest, ParseAccessToken) {
160   // Multiple attempts with random secrets.
161   const auto kStartTime = base::Time::FromTimeT(1412121212);
162   for (size_t i = 0; i < 1000; ++i) {
163     EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(kStartTime));
164 
165     AuthManager auth{{}, {}, {}, &clock_};
166 
167     auto token =
168         auth.CreateAccessToken(UserInfo{AuthScope::kUser, TestUserId{"5"}},
169                                base::TimeDelta::FromSeconds(i));
170     UserInfo user_info;
171     EXPECT_FALSE(auth_.ParseAccessToken(token, &user_info, nullptr));
172     EXPECT_TRUE(auth.ParseAccessToken(token, &user_info, nullptr));
173     EXPECT_EQ(AuthScope::kUser, user_info.scope());
174     EXPECT_EQ(TestUserId{"5"}, user_info.id());
175 
176     EXPECT_CALL(clock_, Now())
177         .WillRepeatedly(Return(kStartTime + base::TimeDelta::FromSeconds(i)));
178     EXPECT_TRUE(auth.ParseAccessToken(token, &user_info, nullptr));
179 
180     auto extended =
181         DelegateToUser(token, base::TimeDelta::FromSeconds(1000),
182                        UserInfo{AuthScope::kUser, TestUserId{"234"}});
183     EXPECT_FALSE(auth.ParseAccessToken(extended, &user_info, nullptr));
184 
185     EXPECT_CALL(clock_, Now())
186         .WillRepeatedly(
187             Return(kStartTime + base::TimeDelta::FromSeconds(i + 1)));
188     EXPECT_FALSE(auth.ParseAccessToken(token, &user_info, nullptr));
189   }
190 }
191 
TEST_F(AuthManagerTest,GetRootClientAuthToken)192 TEST_F(AuthManagerTest, GetRootClientAuthToken) {
193   EXPECT_EQ("WCCDQxkgAUYIGhudoQBCDEBQZgRhYq78I8GtFUZHNBbfGw==",
194             Base64Encode(
195                 auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
196 }
197 
TEST_F(AuthManagerTest,GetRootClientAuthTokenDifferentOwner)198 TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentOwner) {
199   EXPECT_EQ(
200       "WCqDQxkgAUYIGhudoQBMDEpnb29nbGUuY29tUOoLAxSUAZAAv54drarqhag=",
201       Base64Encode(auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud)));
202 }
203 
TEST_F(AuthManagerTest,GetRootClientAuthTokenDifferentTime)204 TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentTime) {
205   auto new_time = clock_.Now() + base::TimeDelta::FromDays(15);
206   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
207   EXPECT_EQ("WCCDQxkgAUYIGhuxZ4BCDEBQjO+OTbjjTzZ/Dvk66nfQqg==",
208             Base64Encode(
209                 auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
210 }
211 
TEST_F(AuthManagerTest,GetRootClientAuthTokenDifferentSecret)212 TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentSecret) {
213   AuthManager auth{kSecret2, {}, kSecret1, &clock_};
214   EXPECT_EQ(
215       "WCCDQxkgAUYIGhudoQBCDEBQ2MZF8YXv5pbtmMxwz9VtLA==",
216       Base64Encode(auth.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
217 }
218 
TEST_F(AuthManagerTest,IsValidAuthToken)219 TEST_F(AuthManagerTest, IsValidAuthToken) {
220   EXPECT_TRUE(auth_.IsValidAuthToken(
221       auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient), nullptr));
222   // Multiple attempts with random secrets.
223   for (size_t i = 0; i < 1000; ++i) {
224     AuthManager auth{{}, {}, {}, &clock_};
225 
226     auto token = auth.GetRootClientAuthToken(RootClientTokenOwner::kClient);
227     EXPECT_FALSE(auth_.IsValidAuthToken(token, nullptr));
228     EXPECT_TRUE(auth.IsValidAuthToken(token, nullptr));
229   }
230 }
231 
TEST_F(AuthManagerTest,CreateSessionId)232 TEST_F(AuthManagerTest, CreateSessionId) {
233   EXPECT_EQ("463315200:1", auth_.CreateSessionId());
234 }
235 
TEST_F(AuthManagerTest,IsValidSessionId)236 TEST_F(AuthManagerTest, IsValidSessionId) {
237   EXPECT_TRUE(auth_.IsValidSessionId("463315200:1"));
238   EXPECT_TRUE(auth_.IsValidSessionId("463315200:2"));
239   EXPECT_TRUE(auth_.IsValidSessionId("463315150"));
240 
241   // Future
242   EXPECT_FALSE(auth_.IsValidSessionId("463315230:1"));
243 
244   // Expired
245   EXPECT_FALSE(auth_.IsValidSessionId("463315100:1"));
246 }
247 
TEST_F(AuthManagerTest,CreateAccessTokenFromAuth)248 TEST_F(AuthManagerTest, CreateAccessTokenFromAuth) {
249   std::vector<uint8_t> access_token;
250   AuthScope scope;
251   base::TimeDelta ttl;
252   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud);
253   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
254                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
255   EXPECT_EQ(
256       "WE+IQxkgAUYIGhudoQBMDEpnb29nbGUuY29tRggaG52hAEYFGhudpOhCAQ5FCUMyMzRNEUs0"
257       "NjMzMTUyMDA6MVCRVKU+0SpOoBppnwqdKMwP",
258       Base64Encode(extended));
259   EXPECT_TRUE(
260       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
261                                       &access_token, &scope, &ttl, nullptr));
262   UserInfo user_info;
263   EXPECT_TRUE(auth_.ParseAccessToken(access_token, &user_info, nullptr));
264   EXPECT_EQ(scope, user_info.scope());
265   EXPECT_EQ(AuthScope::kUser, user_info.scope());
266 
267   EXPECT_EQ(TestUserId{"234"}, user_info.id());
268 }
269 
TEST_F(AuthManagerTest,CreateAccessTokenFromAuthNotMinted)270 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthNotMinted) {
271   std::vector<uint8_t> access_token;
272   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
273   ErrorPtr error;
274   EXPECT_FALSE(auth_.CreateAccessTokenFromAuth(
275       root, base::TimeDelta::FromDays(1), nullptr, nullptr, nullptr, &error));
276   EXPECT_TRUE(error->HasError("invalidAuthCode"));
277 }
278 
TEST_F(AuthManagerTest,CreateAccessTokenFromAuthValidateAfterSomeTime)279 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthValidateAfterSomeTime) {
280   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
281   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
282                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
283 
284   // new_time < session_id_expiration < token_expiration.
285   auto new_time = clock_.Now() + base::TimeDelta::FromSeconds(15);
286   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
287   EXPECT_TRUE(
288       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
289                                       nullptr, nullptr, nullptr, nullptr));
290 }
291 
TEST_F(AuthManagerTest,CreateAccessTokenFromAuthExpired)292 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthExpired) {
293   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
294   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(10),
295                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
296   ErrorPtr error;
297 
298   // token_expiration < new_time < session_id_expiration.
299   auto new_time = clock_.Now() + base::TimeDelta::FromSeconds(15);
300   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
301   EXPECT_FALSE(
302       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
303                                       nullptr, nullptr, nullptr, &error));
304   EXPECT_TRUE(error->HasError("invalidAuthCode"));
305 }
306 
TEST_F(AuthManagerTest,CreateAccessTokenFromAuthExpiredSessionid)307 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthExpiredSessionid) {
308   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
309   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
310                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
311   ErrorPtr error;
312 
313   // session_id_expiration < new_time < token_expiration.
314   auto new_time = clock_.Now() + base::TimeDelta::FromSeconds(200);
315   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
316   EXPECT_FALSE(
317       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
318                                       nullptr, nullptr, nullptr, &error));
319   EXPECT_TRUE(error->HasError("invalidAuthCode"));
320 }
321 
322 class AuthManagerClaimTest : public testing::Test {
323  public:
SetUp()324   void SetUp() override { EXPECT_EQ(auth_.GetAuthSecret().size(), 32u); }
325 
TestClaim(RootClientTokenOwner owner,RootClientTokenOwner claimer)326   bool TestClaim(RootClientTokenOwner owner, RootClientTokenOwner claimer) {
327     Config::Transaction change{&config_};
328     change.set_root_client_token_owner(owner);
329     change.Commit();
330     return !auth_.ClaimRootClientAuthToken(claimer, nullptr).empty();
331   }
332 
333  protected:
334   Config config_{nullptr};
335   AuthManager auth_{&config_, {}};
336 };
337 
TEST_F(AuthManagerClaimTest,WithPreviosOwner)338 TEST_F(AuthManagerClaimTest, WithPreviosOwner) {
339   EXPECT_DEATH(
340       TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kNone), "");
341   EXPECT_DEATH(
342       TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kNone),
343       "");
344   EXPECT_DEATH(
345       TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kNone), "");
346   EXPECT_TRUE(
347       TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kClient));
348   EXPECT_FALSE(
349       TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kClient));
350   EXPECT_FALSE(
351       TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kClient));
352   EXPECT_TRUE(
353       TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kCloud));
354   EXPECT_TRUE(
355       TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kCloud));
356   EXPECT_TRUE(
357       TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kCloud));
358 }
359 
TEST_F(AuthManagerClaimTest,NormalClaim)360 TEST_F(AuthManagerClaimTest, NormalClaim) {
361   auto token =
362       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
363   EXPECT_FALSE(auth_.IsValidAuthToken(token, nullptr));
364   EXPECT_EQ(RootClientTokenOwner::kNone,
365             config_.GetSettings().root_client_token_owner);
366 
367   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token, nullptr));
368   EXPECT_TRUE(auth_.IsValidAuthToken(token, nullptr));
369   EXPECT_EQ(RootClientTokenOwner::kCloud,
370             config_.GetSettings().root_client_token_owner);
371 }
372 
TEST_F(AuthManagerClaimTest,DoubleConfirm)373 TEST_F(AuthManagerClaimTest, DoubleConfirm) {
374   auto token =
375       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
376   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token, nullptr));
377   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token, nullptr));
378 }
379 
TEST_F(AuthManagerClaimTest,DoubleClaim)380 TEST_F(AuthManagerClaimTest, DoubleClaim) {
381   auto token1 =
382       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
383   auto token2 =
384       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
385   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token1, nullptr));
386   EXPECT_FALSE(auth_.ConfirmClientAuthToken(token2, nullptr));
387 }
388 
TEST_F(AuthManagerClaimTest,TokenOverflow)389 TEST_F(AuthManagerClaimTest, TokenOverflow) {
390   auto token =
391       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
392   for (size_t i = 0; i < 100; ++i)
393     auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
394   EXPECT_FALSE(auth_.ConfirmClientAuthToken(token, nullptr));
395 }
396 
397 }  // namespace privet
398 }  // namespace weave
399