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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/login/owner_manager.h"
6 #include "chrome/browser/chromeos/login/owner_manager_unittest.h"
7
8 #include <string>
9
10 #include "base/file_path.h"
11 #include "base/file_util.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_temp_dir.h"
14 #include "crypto/nss_util.h"
15 #include "crypto/rsa_private_key.h"
16 #include "chrome/browser/chromeos/login/mock_owner_key_utils.h"
17 #include "content/browser/browser_thread.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using ::crypto::RSAPrivateKey;
22 using ::testing::DoAll;
23 using ::testing::Eq;
24 using ::testing::Invoke;
25 using ::testing::Return;
26 using ::testing::SetArgumentPointee;
27 using ::testing::_;
28
29 namespace chromeos {
30
31 class OwnerManagerTest : public ::testing::Test {
32 public:
OwnerManagerTest()33 OwnerManagerTest()
34 : message_loop_(MessageLoop::TYPE_UI),
35 ui_thread_(BrowserThread::UI, &message_loop_),
36 file_thread_(BrowserThread::FILE),
37 mock_(new MockKeyUtils),
38 injector_(mock_) /* injector_ takes ownership of mock_ */ {
39 }
~OwnerManagerTest()40 virtual ~OwnerManagerTest() {}
41
SetUp()42 virtual void SetUp() {
43 crypto::OpenPersistentNSSDB(); // TODO(cmasone): use test DB instead
44 fake_private_key_.reset(RSAPrivateKey::Create(256));
45 ASSERT_TRUE(fake_private_key_->ExportPublicKey(&fake_public_key_));
46
47 // Mimic ownership.
48 ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
49 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(tmpdir_.path(), &tmpfile_));
50
51 file_thread_.Start();
52 OwnerKeyUtils::set_factory(&injector_);
53 }
54
TearDown()55 virtual void TearDown() {
56 OwnerKeyUtils::set_factory(NULL);
57 }
58
StartUnowned()59 void StartUnowned() {
60 file_util::Delete(tmpfile_, false);
61 }
62
InjectKeys(OwnerManager * manager)63 void InjectKeys(OwnerManager* manager) {
64 manager->public_key_ = fake_public_key_;
65 manager->private_key_.reset(fake_private_key_.release());
66 }
67
68 ScopedTempDir tmpdir_;
69 FilePath tmpfile_;
70
71 MessageLoop message_loop_;
72 BrowserThread ui_thread_;
73 BrowserThread file_thread_;
74
75 std::vector<uint8> fake_public_key_;
76 scoped_ptr<RSAPrivateKey> fake_private_key_;
77
78 MockKeyUtils* mock_;
79 MockInjector injector_;
80
81 };
82
TEST_F(OwnerManagerTest,UpdateOwnerKey)83 TEST_F(OwnerManagerTest, UpdateOwnerKey) {
84 scoped_refptr<OwnerManager> manager(new OwnerManager);
85
86 MockKeyUpdateUser delegate;
87 BrowserThread::PostTask(
88 BrowserThread::FILE, FROM_HERE,
89 NewRunnableMethod(manager.get(),
90 &OwnerManager::UpdateOwnerKey,
91 BrowserThread::UI,
92 std::vector<uint8>(),
93 &delegate));
94 message_loop_.Run();
95 }
96
TEST_F(OwnerManagerTest,LoadOwnerKeyFail)97 TEST_F(OwnerManagerTest, LoadOwnerKeyFail) {
98 StartUnowned();
99 MockKeyLoadObserver loader;
100 scoped_refptr<OwnerManager> manager(new OwnerManager);
101
102 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
103 .WillRepeatedly(Return(tmpfile_));
104 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
105 .WillOnce(Return(false))
106 .RetiresOnSaturation();
107
108 BrowserThread::PostTask(
109 BrowserThread::FILE, FROM_HERE,
110 NewRunnableMethod(manager.get(),
111 &OwnerManager::LoadOwnerKey));
112 message_loop_.Run();
113 }
114
TEST_F(OwnerManagerTest,AlreadyLoadedOwnerKey)115 TEST_F(OwnerManagerTest, AlreadyLoadedOwnerKey) {
116 MockKeyLoadObserver loader;
117 loader.ExpectKeyFetchSuccess(true);
118 scoped_refptr<OwnerManager> manager(new OwnerManager);
119
120 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
121 .WillRepeatedly(Return(tmpfile_));
122
123 InjectKeys(manager.get());
124
125 BrowserThread::PostTask(
126 BrowserThread::FILE, FROM_HERE,
127 NewRunnableMethod(manager.get(),
128 &OwnerManager::LoadOwnerKey));
129
130 message_loop_.Run();
131 }
132
TEST_F(OwnerManagerTest,LoadOwnerKey)133 TEST_F(OwnerManagerTest, LoadOwnerKey) {
134 MockKeyLoadObserver loader;
135 loader.ExpectKeyFetchSuccess(true);
136 scoped_refptr<OwnerManager> manager(new OwnerManager);
137
138 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
139 .WillRepeatedly(Return(tmpfile_));
140 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
141 .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
142 Return(true)))
143 .RetiresOnSaturation();
144
145 BrowserThread::PostTask(
146 BrowserThread::FILE, FROM_HERE,
147 NewRunnableMethod(manager.get(),
148 &OwnerManager::LoadOwnerKey));
149
150 message_loop_.Run();
151 }
152
TEST_F(OwnerManagerTest,GetKeyFailDuringVerify)153 TEST_F(OwnerManagerTest, GetKeyFailDuringVerify) {
154 StartUnowned();
155 MockKeyLoadObserver loader;
156 loader.ExpectKeyFetchSuccess(false);
157 scoped_refptr<OwnerManager> manager(new OwnerManager);
158
159 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
160 .WillRepeatedly(Return(tmpfile_));
161 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
162 .WillOnce(Return(false))
163 .RetiresOnSaturation();
164
165 MockKeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
166
167 BrowserThread::PostTask(
168 BrowserThread::FILE, FROM_HERE,
169 NewRunnableMethod(manager.get(),
170 &OwnerManager::Verify,
171 BrowserThread::UI,
172 std::string(),
173 std::vector<uint8>(),
174 &delegate));
175 message_loop_.Run();
176 }
177
TEST_F(OwnerManagerTest,AlreadyHaveKeysVerify)178 TEST_F(OwnerManagerTest, AlreadyHaveKeysVerify) {
179 scoped_refptr<OwnerManager> manager(new OwnerManager);
180
181 std::string data;
182 std::vector<uint8> sig(0, 2);
183
184 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
185 .WillRepeatedly(Return(tmpfile_));
186 EXPECT_CALL(*mock_, Verify(Eq(data), Eq(sig), Eq(fake_public_key_)))
187 .WillOnce(Return(true))
188 .RetiresOnSaturation();
189
190 InjectKeys(manager.get());
191 MockKeyUser delegate(OwnerManager::SUCCESS);
192
193 BrowserThread::PostTask(
194 BrowserThread::FILE, FROM_HERE,
195 NewRunnableMethod(manager.get(),
196 &OwnerManager::Verify,
197 BrowserThread::UI,
198 data,
199 sig,
200 &delegate));
201 message_loop_.Run();
202 }
203
TEST_F(OwnerManagerTest,GetKeyAndVerify)204 TEST_F(OwnerManagerTest, GetKeyAndVerify) {
205 MockKeyLoadObserver loader;
206 loader.ExpectKeyFetchSuccess(true);
207 loader.SetQuitOnKeyFetch(false);
208 scoped_refptr<OwnerManager> manager(new OwnerManager);
209
210 std::string data;
211 std::vector<uint8> sig(0, 2);
212
213 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
214 .WillRepeatedly(Return(tmpfile_));
215 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
216 .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
217 Return(true)))
218 .RetiresOnSaturation();
219 EXPECT_CALL(*mock_, Verify(Eq(data), Eq(sig), Eq(fake_public_key_)))
220 .WillOnce(Return(true))
221 .RetiresOnSaturation();
222
223 MockKeyUser delegate(OwnerManager::SUCCESS);
224
225 BrowserThread::PostTask(
226 BrowserThread::FILE, FROM_HERE,
227 NewRunnableMethod(manager.get(),
228 &OwnerManager::Verify,
229 BrowserThread::UI,
230 data,
231 sig,
232 &delegate));
233 message_loop_.Run();
234 }
235
TEST_F(OwnerManagerTest,AlreadyHaveKeysSign)236 TEST_F(OwnerManagerTest, AlreadyHaveKeysSign) {
237 scoped_refptr<OwnerManager> manager(new OwnerManager);
238
239 std::string data;
240 std::vector<uint8> sig(0, 2);
241
242 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
243 .WillRepeatedly(Return(tmpfile_));
244 EXPECT_CALL(*mock_, Sign(Eq(data), _, Eq(fake_private_key_.get())))
245 .WillOnce(DoAll(SetArgumentPointee<1>(sig),
246 Return(true)))
247 .RetiresOnSaturation();
248
249 InjectKeys(manager.get());
250 MockSigner delegate(OwnerManager::SUCCESS, sig);
251
252 BrowserThread::PostTask(
253 BrowserThread::FILE, FROM_HERE,
254 NewRunnableMethod(manager.get(),
255 &OwnerManager::Sign,
256 BrowserThread::UI,
257 data,
258 &delegate));
259 message_loop_.Run();
260 }
261
262 } // namespace chromeos
263