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
22using ::crypto::RSAPrivateKey;
23using ::testing::DoAll;
24using ::testing::Eq;
25using ::testing::Invoke;
26using ::testing::Return;
27using ::testing::SetArgumentPointee;
28using ::testing::_;
29
30
31namespace chromeos {
32
33class OwnershipServiceTest : public ::testing::Test {
34 public:
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  }
42  virtual ~OwnershipServiceTest() {}
43
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
59  virtual void TearDown() {
60    OwnerKeyUtils::set_factory(NULL);
61    service_.reset(NULL);
62  }
63
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
83TEST_F(OwnershipServiceTest, IsOwned) {
84  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
85      .WillRepeatedly(Return(tmpfile_));
86  EXPECT_TRUE(service_->IsAlreadyOwned());
87}
88
89TEST_F(OwnershipServiceTest, IsOwnershipTaken) {
90  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
91      .WillRepeatedly(Return(tmpfile_));
92  EXPECT_TRUE(service_->GetStatus(true) == OwnershipService::OWNERSHIP_TAKEN);
93}
94
95TEST_F(OwnershipServiceTest, IsUnowned) {
96  StartUnowned();
97
98  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
99      .WillRepeatedly(Return(tmpfile_));
100  EXPECT_FALSE(service_->IsAlreadyOwned());
101}
102
103TEST_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
111TEST_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
125TEST_F(OwnershipServiceTest, UpdateOwnerKey) {
126  MockKeyUpdateUser delegate;
127  service_->StartUpdateOwnerKey(std::vector<uint8>(), &delegate);
128
129  message_loop_.Run();
130}
131
132TEST_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
147TEST_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
159TEST_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
175TEST_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
199TEST_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