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/ownership_service.h"
6
7 #include <string>
8
9 #include "base/file_path.h"
10 #include "base/file_util.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.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 "chrome/browser/chromeos/login/owner_manager_unittest.h"
18 #include "content/browser/browser_thread.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using ::crypto::RSAPrivateKey;
23 using ::testing::DoAll;
24 using ::testing::Eq;
25 using ::testing::Invoke;
26 using ::testing::Return;
27 using ::testing::SetArgumentPointee;
28 using ::testing::_;
29
30
31 namespace chromeos {
32
33 class OwnershipServiceTest : public ::testing::Test {
34 public:
OwnershipServiceTest()35 OwnershipServiceTest()
36 : message_loop_(MessageLoop::TYPE_UI),
37 ui_thread_(BrowserThread::UI, &message_loop_),
38 file_thread_(BrowserThread::FILE),
39 mock_(new MockKeyUtils),
40 injector_(mock_) /* injector_ takes ownership of mock_ */ {
41 }
~OwnershipServiceTest()42 virtual ~OwnershipServiceTest() {}
43
SetUp()44 virtual void SetUp() {
45 crypto::OpenPersistentNSSDB(); // TODO(cmasone): use test DB instead
46 fake_private_key_.reset(RSAPrivateKey::Create(256));
47 ASSERT_TRUE(fake_private_key_->ExportPublicKey(&fake_public_key_));
48
49 // Mimic ownership.
50 ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
51 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(tmpdir_.path(), &tmpfile_));
52
53 file_thread_.Start();
54 OwnerKeyUtils::set_factory(&injector_);
55 service_.reset(new OwnershipService); // must happen AFTER set_factory().
56 service_->Prewarm();
57 }
58
TearDown()59 virtual void TearDown() {
60 OwnerKeyUtils::set_factory(NULL);
61 service_.reset(NULL);
62 }
63
StartUnowned()64 void StartUnowned() {
65 file_util::Delete(tmpfile_, false);
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 scoped_ptr<OwnershipService> service_;
81 };
82
TEST_F(OwnershipServiceTest,IsOwned)83 TEST_F(OwnershipServiceTest, IsOwned) {
84 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
85 .WillRepeatedly(Return(tmpfile_));
86 EXPECT_TRUE(service_->IsAlreadyOwned());
87 }
88
TEST_F(OwnershipServiceTest,IsOwnershipTaken)89 TEST_F(OwnershipServiceTest, IsOwnershipTaken) {
90 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
91 .WillRepeatedly(Return(tmpfile_));
92 EXPECT_TRUE(service_->GetStatus(true) == OwnershipService::OWNERSHIP_TAKEN);
93 }
94
TEST_F(OwnershipServiceTest,IsUnowned)95 TEST_F(OwnershipServiceTest, IsUnowned) {
96 StartUnowned();
97
98 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
99 .WillRepeatedly(Return(tmpfile_));
100 EXPECT_FALSE(service_->IsAlreadyOwned());
101 }
102
TEST_F(OwnershipServiceTest,IsOwnershipNone)103 TEST_F(OwnershipServiceTest, IsOwnershipNone) {
104 StartUnowned();
105
106 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
107 .WillRepeatedly(Return(tmpfile_));
108 EXPECT_TRUE(service_->GetStatus(true) == OwnershipService::OWNERSHIP_NONE);
109 }
110
TEST_F(OwnershipServiceTest,LoadOwnerKeyFail)111 TEST_F(OwnershipServiceTest, LoadOwnerKeyFail) {
112 MockKeyLoadObserver loader;
113 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
114 .WillRepeatedly(Return(tmpfile_));
115 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
116 .WillOnce(Return(false))
117 .RetiresOnSaturation();
118
119 service_->StartLoadOwnerKeyAttempt();
120
121 // Run remaining events, until ExportPublicKeyViaDbus().
122 message_loop_.Run();
123 }
124
TEST_F(OwnershipServiceTest,UpdateOwnerKey)125 TEST_F(OwnershipServiceTest, UpdateOwnerKey) {
126 MockKeyUpdateUser delegate;
127 service_->StartUpdateOwnerKey(std::vector<uint8>(), &delegate);
128
129 message_loop_.Run();
130 }
131
TEST_F(OwnershipServiceTest,LoadOwnerKey)132 TEST_F(OwnershipServiceTest, LoadOwnerKey) {
133 MockKeyLoadObserver loader;
134 loader.ExpectKeyFetchSuccess(true);
135
136 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
137 .WillRepeatedly(Return(tmpfile_));
138 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
139 .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
140 Return(true)))
141 .RetiresOnSaturation();
142 service_->StartLoadOwnerKeyAttempt();
143
144 message_loop_.Run();
145 }
146
TEST_F(OwnershipServiceTest,NotYetOwnedVerify)147 TEST_F(OwnershipServiceTest, NotYetOwnedVerify) {
148 StartUnowned();
149
150 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
151 .WillRepeatedly(Return(tmpfile_));
152
153 MockKeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
154 service_->StartVerifyAttempt("", std::vector<uint8>(), &delegate);
155
156 message_loop_.Run();
157 }
158
TEST_F(OwnershipServiceTest,GetKeyFailDuringVerify)159 TEST_F(OwnershipServiceTest, GetKeyFailDuringVerify) {
160 MockKeyLoadObserver loader;
161 loader.ExpectKeyFetchSuccess(false);
162
163 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
164 .WillRepeatedly(Return(tmpfile_));
165 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
166 .WillOnce(Return(false))
167 .RetiresOnSaturation();
168
169 MockKeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
170 service_->StartVerifyAttempt("", std::vector<uint8>(), &delegate);
171
172 message_loop_.Run();
173 }
174
TEST_F(OwnershipServiceTest,GetKeyAndVerify)175 TEST_F(OwnershipServiceTest, GetKeyAndVerify) {
176 MockKeyLoadObserver loader;
177 loader.ExpectKeyFetchSuccess(true);
178 loader.SetQuitOnKeyFetch(false);
179
180 std::string data;
181 std::vector<uint8> sig(0, 2);
182
183 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
184 .WillRepeatedly(Return(tmpfile_));
185 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
186 .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
187 Return(true)))
188 .RetiresOnSaturation();
189 EXPECT_CALL(*mock_, Verify(Eq(data), Eq(sig), Eq(fake_public_key_)))
190 .WillOnce(Return(true))
191 .RetiresOnSaturation();
192
193 MockKeyUser delegate(OwnerManager::SUCCESS);
194 service_->StartVerifyAttempt(data, sig, &delegate);
195
196 message_loop_.Run();
197 }
198
TEST_F(OwnershipServiceTest,GetKeyAndFailVerify)199 TEST_F(OwnershipServiceTest, GetKeyAndFailVerify) {
200 MockKeyLoadObserver loader;
201 loader.ExpectKeyFetchSuccess(true);
202 loader.SetQuitOnKeyFetch(false);
203
204 std::string data;
205 std::vector<uint8> sig(0, 2);
206
207 EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
208 .WillRepeatedly(Return(tmpfile_));
209 EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
210 .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
211 Return(true)))
212 .RetiresOnSaturation();
213 EXPECT_CALL(*mock_, Verify(Eq(data), Eq(sig), Eq(fake_public_key_)))
214 .WillOnce(Return(false))
215 .RetiresOnSaturation();
216
217 MockKeyUser delegate(OwnerManager::OPERATION_FAILED);
218 service_->StartVerifyAttempt(data, sig, &delegate);
219
220 message_loop_.Run();
221 }
222
223 } // namespace chromeos
224