Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: chrome/browser/chromeos/login/owner_manager_unittest.cc

Issue 3058021: OwnerManager, allows use of OwnerKeyUtils to take ownership of a device (Closed)
Patch Set: added a lot of comments per gauravsh Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/chromeos/login/owner_manager.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 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/chromeos/login/owner_manager.h"
6
7 #include <cert.h>
8 #include <keyhi.h>
9 #include <keythi.h> // KeyType enum
10 #include <pk11pub.h>
11 #include <stdlib.h>
12
13 #include <string>
14
15 #include "base/file_path.h"
16 #include "base/file_util.h"
17 #include "base/logging.h"
18 #include "base/nss_util_internal.h"
19 #include "base/nss_util.h"
20 #include "base/scoped_temp_dir.h"
21 #include "chrome/browser/chrome_thread.h"
22 #include "chrome/common/notification_registrar.h"
23 #include "chrome/common/notification_service.h"
24 #include "chrome/common/notification_type.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 using ::testing::DoAll;
29 using ::testing::Invoke;
30 using ::testing::Return;
31 using ::testing::SetArgumentPointee;
32 using ::testing::_;
33
34 namespace chromeos {
35
36 namespace {
37
38 class MockKeyUtils : public OwnerKeyUtils {
39 public:
40 MockKeyUtils() {}
41 ~MockKeyUtils() {}
42 MOCK_METHOD2(GenerateKeyPair, bool(SECKEYPrivateKey** private_key_out,
43 SECKEYPublicKey** public_key_out));
44 MOCK_METHOD1(ExportPublicKeyViaDbus, bool(SECKEYPublicKey* key));
45 MOCK_METHOD2(ExportPublicKeyToFile, bool(SECKEYPublicKey* key,
46 const FilePath& key_file));
47 MOCK_METHOD1(ImportPublicKey, SECKEYPublicKey*(const FilePath& key_file));
48 MOCK_METHOD1(FindPrivateKey, SECKEYPrivateKey*(SECKEYPublicKey* key));
49 MOCK_METHOD2(DestroyKeys, void(SECKEYPrivateKey* private_key,
50 SECKEYPublicKey* public_key));
51 MOCK_METHOD0(GetOwnerKeyFilePath, FilePath());
52 };
53
54 class MockInjector : public OwnerKeyUtils::Factory {
55 public:
56 // Takes ownership of |mock|.
57 explicit MockInjector(MockKeyUtils* mock) :
58 transient_(mock),
59 delete_transient_(true) {
60 }
61
62 virtual ~MockInjector() {
63 if (delete_transient_)
64 delete transient_;
65 }
66
67 // If this is called, its caller takes ownership of |transient_|.
68 // If it's never called, |transient_| remains our problem.
69 OwnerKeyUtils* CreateOwnerKeyUtils() {
70 delete_transient_ = false;
71 return transient_;
72 }
73
74 private:
75 MockKeyUtils* transient_;
76 bool delete_transient_;
77 };
78
79 class KeyUser : public OwnerManager::Delegate {
80 public:
81 explicit KeyUser(const OwnerManager::KeyOpCode expected)
82 : expected_(expected) {
83 }
84
85 virtual ~KeyUser() {}
86
87 void OnKeyOpComplete(const OwnerManager::KeyOpCode return_code,
88 const std::string& payload) {
89 MessageLoop::current()->Quit();
90 EXPECT_EQ(expected_, return_code);
91 }
92
93 const OwnerManager::KeyOpCode expected_;
94 };
95
96 static bool Win(SECKEYPublicKey* key) {
97 MessageLoop::current()->Quit();
98 return true;
99 }
100
101 static bool Fail(SECKEYPublicKey* key) {
102 MessageLoop::current()->Quit();
103 return false;
104 }
105
106 } // anonymous namespace
107
108 class OwnerManagerTest : public ::testing::Test,
109 public NotificationObserver {
110 public:
111 OwnerManagerTest()
112 : message_loop_(MessageLoop::TYPE_UI),
113 ui_thread_(ChromeThread::UI, &message_loop_),
114 file_thread_(ChromeThread::FILE),
115 fake_public_key_(reinterpret_cast<SECKEYPublicKey*>(7)),
116 fake_private_key_(reinterpret_cast<SECKEYPrivateKey*>(7)),
117 success_expected_(false),
118 quit_on_observe_(true),
119 mock_(new MockKeyUtils),
120 injector_(mock_) /* injector_ takes ownership of mock_ */ {
121 registrar_.Add(
122 this,
123 NotificationType::OWNER_KEY_FETCH_ATTEMPT_COMPLETE,
124 NotificationService::AllSources());
125 }
126 virtual ~OwnerManagerTest() {}
127
128 virtual void SetUp() {
129 // Mimic ownership.
130 ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
131 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(tmpdir_.path(), &tmpfile_));
132
133 file_thread_.Start();
134 OwnerKeyUtils::set_factory(&injector_);
135 }
136
137 virtual void TearDown() {
138 OwnerKeyUtils::set_factory(NULL);
139 }
140
141 void StartUnowned() {
142 file_util::Delete(tmpfile_, false);
143 }
144
145 void InjectKeys(OwnerManager* manager) {
146 manager->public_key_ = fake_public_key_;
147 manager->private_key_ = fake_private_key_;
148 }
149
150 // NotificationObserver implementation.
151 virtual void Observe(NotificationType type,
152 const NotificationSource& source,
153 const NotificationDetails& details) {
154 if (type == NotificationType::OWNER_KEY_FETCH_ATTEMPT_COMPLETE) {
155 EXPECT_EQ(success_expected_,
156 NULL != *Details<SECKEYPublicKey*>(details).ptr());
157 if (quit_on_observe_)
158 MessageLoop::current()->Quit();
159 }
160 }
161
162 void ExpectKeyFetchSuccess(bool should_succeed) {
163 success_expected_ = should_succeed;
164 }
165 void SetQuitOnKeyFetch(bool should_quit) { quit_on_observe_ = should_quit; }
166
167 ScopedTempDir tmpdir_;
168 FilePath tmpfile_;
169
170 MessageLoop message_loop_;
171 ChromeThread ui_thread_;
172 ChromeThread file_thread_;
173
174 SECKEYPublicKey* fake_public_key_;
175 SECKEYPrivateKey* fake_private_key_;
176
177 NotificationRegistrar registrar_;
178 bool success_expected_;
179 bool quit_on_observe_;
180
181 MockKeyUtils* mock_;
182 MockInjector injector_;
183 };
184
185 TEST_F(OwnerManagerTest, LoadKeyUnowned) {
186 StartUnowned();
187
188 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
189 .WillRepeatedly(Return(tmpfile_));
190
191 scoped_refptr<OwnerManager> manager(new OwnerManager);
192 EXPECT_FALSE(manager->StartLoadOwnerKeyAttempt());
193 }
194
195 TEST_F(OwnerManagerTest, LoadOwnerKeyFail) {
196 SECKEYPublicKey* to_return = NULL;
197
198 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
199 .WillRepeatedly(Return(tmpfile_));
200 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
201 .WillOnce(Return(to_return))
202 .RetiresOnSaturation();
203
204 scoped_refptr<OwnerManager> manager(new OwnerManager);
205 EXPECT_TRUE(manager->StartLoadOwnerKeyAttempt());
206
207 // Run remaining events, until ExportPublicKeyViaDbus().
208 message_loop_.Run();
209 }
210
211 TEST_F(OwnerManagerTest, LoadOwnerKey) {
212 ExpectKeyFetchSuccess(true);
213
214 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
215 .WillRepeatedly(Return(tmpfile_));
216 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
217 .WillOnce(Return(fake_public_key_))
218 .RetiresOnSaturation();
219
220 scoped_refptr<OwnerManager> manager(new OwnerManager);
221 EXPECT_TRUE(manager->StartLoadOwnerKeyAttempt());
222
223 // Run remaining events, until ExportPublicKeyViaDbus().
224 message_loop_.Run();
225 }
226
227 TEST_F(OwnerManagerTest, TakeOwnershipAlreadyOwned) {
228
229 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
230 .WillRepeatedly(Return(tmpfile_));
231
232 scoped_refptr<OwnerManager> manager(new OwnerManager);
233 EXPECT_FALSE(manager->StartTakeOwnershipAttempt());
234 }
235
236 TEST_F(OwnerManagerTest, KeyGenerationFail) {
237 StartUnowned();
238
239 EXPECT_CALL(*mock_, GenerateKeyPair(_, _))
240 .WillOnce(Return(false))
241 .RetiresOnSaturation();
242 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
243 .WillRepeatedly(Return(tmpfile_));
244
245 scoped_refptr<OwnerManager> manager(new OwnerManager);
246 EXPECT_TRUE(manager->StartTakeOwnershipAttempt());
247
248 message_loop_.Run();
249 }
250
251 TEST_F(OwnerManagerTest, KeyExportFail) {
252 StartUnowned();
253
254 EXPECT_CALL(*mock_, GenerateKeyPair(_, _))
255 .WillOnce(Return(true))
256 .RetiresOnSaturation();
257 EXPECT_CALL(*mock_, ExportPublicKeyViaDbus(_))
258 .WillOnce(Invoke(Fail))
259 .RetiresOnSaturation();
260 EXPECT_CALL(*mock_, DestroyKeys(_, _))
261 .Times(1)
262 .RetiresOnSaturation();
263 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
264 .WillRepeatedly(Return(tmpfile_));
265
266 scoped_refptr<OwnerManager> manager(new OwnerManager);
267 EXPECT_TRUE(manager->StartTakeOwnershipAttempt());
268
269 message_loop_.Run();
270 }
271
272 TEST_F(OwnerManagerTest, TakeOwnership) {
273 StartUnowned();
274 ExpectKeyFetchSuccess(true);
275
276 EXPECT_CALL(*mock_, GenerateKeyPair(_, _))
277 .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
278 Return(true)))
279 .RetiresOnSaturation();
280 EXPECT_CALL(*mock_, ExportPublicKeyViaDbus(_))
281 .WillOnce(Invoke(Win))
282 .RetiresOnSaturation();
283 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
284 .WillRepeatedly(Return(tmpfile_));
285
286 scoped_refptr<OwnerManager> manager(new OwnerManager);
287 EXPECT_TRUE(manager->StartTakeOwnershipAttempt());
288
289 message_loop_.Run();
290 }
291
292 TEST_F(OwnerManagerTest, NotYetOwnedVerify) {
293 StartUnowned();
294
295 // Since this shouldn't happen, don't want it to end the test if it does.
296 SetQuitOnKeyFetch(false);
297
298 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
299 .WillRepeatedly(Return(tmpfile_));
300
301 scoped_refptr<OwnerManager> manager(new OwnerManager);
302 KeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
303 EXPECT_FALSE(manager->StartVerifyAttempt("", "", &delegate));
304 }
305
306 TEST_F(OwnerManagerTest, AlreadyHaveKeysVerify) {
307 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
308 .WillRepeatedly(Return(tmpfile_));
309
310 scoped_refptr<OwnerManager> manager(new OwnerManager);
311 InjectKeys(manager.get());
312 KeyUser delegate(OwnerManager::SUCCESS);
313 EXPECT_TRUE(manager->StartVerifyAttempt("", "", &delegate));
314
315 message_loop_.Run();
316 }
317
318 TEST_F(OwnerManagerTest, GetKeyFailDuringVerify) {
319 ExpectKeyFetchSuccess(false);
320 SECKEYPublicKey* to_return = NULL;
321
322 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
323 .WillRepeatedly(Return(tmpfile_));
324 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
325 .WillOnce(Return(to_return))
326 .RetiresOnSaturation();
327
328 scoped_refptr<OwnerManager> manager(new OwnerManager);
329 KeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
330 EXPECT_TRUE(manager->StartVerifyAttempt("", "", &delegate));
331
332 message_loop_.Run();
333 }
334
335 TEST_F(OwnerManagerTest, GetKeyAndVerify) {
336 ExpectKeyFetchSuccess(true);
337 SetQuitOnKeyFetch(false);
338
339 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
340 .WillRepeatedly(Return(tmpfile_));
341 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_))
342 .WillOnce(Return(fake_public_key_))
343 .RetiresOnSaturation();
344
345 scoped_refptr<OwnerManager> manager(new OwnerManager);
346 KeyUser delegate(OwnerManager::SUCCESS);
347 EXPECT_TRUE(manager->StartVerifyAttempt("", "", &delegate));
348
349 message_loop_.Run();
350 }
351
352 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/owner_manager.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698