ownership_service_unittest.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
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/ownership_service.h"
6
7#include <string>
8
9#include "base/crypto/rsa_private_key.h"
10#include "base/file_path.h"
11#include "base/file_util.h"
12#include "base/logging.h"
13#include "base/nss_util.h"
14#include "base/scoped_ptr.h"
15#include "base/scoped_temp_dir.h"
16#include "chrome/browser/browser_thread.h"
17#include "chrome/browser/chromeos/login/mock_owner_key_utils.h"
18#include "chrome/browser/chromeos/login/owner_manager_unittest.h"
19#include "testing/gmock/include/gmock/gmock.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22using ::base::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    base::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
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, IsUnowned) {
90  StartUnowned();
91
92  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
93      .WillRepeatedly(Return(tmpfile_));
94  EXPECT_FALSE(service_->IsAlreadyOwned());
95}
96
97TEST_F(OwnershipServiceTest, LoadOwnerKeyUnowned) {
98  StartUnowned();
99
100  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
101      .WillRepeatedly(Return(tmpfile_));
102  EXPECT_FALSE(service_->StartLoadOwnerKeyAttempt());
103}
104
105TEST_F(OwnershipServiceTest, LoadOwnerKeyFail) {
106  MockKeyLoadObserver loader;
107  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
108      .WillRepeatedly(Return(tmpfile_));
109  EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
110      .WillOnce(Return(false))
111      .RetiresOnSaturation();
112
113  EXPECT_TRUE(service_->StartLoadOwnerKeyAttempt());
114
115  // Run remaining events, until ExportPublicKeyViaDbus().
116  message_loop_.Run();
117}
118
119TEST_F(OwnershipServiceTest, LoadOwnerKey) {
120  MockKeyLoadObserver loader;
121  loader.ExpectKeyFetchSuccess(true);
122
123  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
124      .WillRepeatedly(Return(tmpfile_));
125  EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
126      .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
127                      Return(true)))
128      .RetiresOnSaturation();
129  EXPECT_TRUE(service_->StartLoadOwnerKeyAttempt());
130
131  message_loop_.Run();
132}
133
134TEST_F(OwnershipServiceTest, TakeOwnershipAlreadyOwned) {
135  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
136      .WillRepeatedly(Return(tmpfile_));
137  EXPECT_FALSE(service_->StartTakeOwnershipAttempt("you"));
138}
139
140TEST_F(OwnershipServiceTest, AttemptKeyGeneration) {
141  // We really only care that we initiate key generation here;
142  // actual key-generation paths are tested in owner_manager_unittest.cc
143  StartUnowned();
144  MockKeyLoadObserver loader;
145  loader.ExpectKeyFetchSuccess(false);
146
147  EXPECT_CALL(*mock_, GenerateKeyPair())
148      .WillOnce(Return(reinterpret_cast<RSAPrivateKey*>(NULL)))
149      .RetiresOnSaturation();
150  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
151      .WillRepeatedly(Return(tmpfile_));
152
153  EXPECT_TRUE(service_->StartTakeOwnershipAttempt("me"));
154
155  message_loop_.Run();
156}
157
158TEST_F(OwnershipServiceTest, NotYetOwnedVerify) {
159  StartUnowned();
160
161  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
162      .WillRepeatedly(Return(tmpfile_));
163  // Create delegate that does not quit the message loop on callback.
164  MockKeyUser delegate(OwnerManager::KEY_UNAVAILABLE, false);
165  service_->StartVerifyAttempt("", std::vector<uint8>(), &delegate);
166}
167
168TEST_F(OwnershipServiceTest, GetKeyFailDuringVerify) {
169  MockKeyLoadObserver loader;
170  loader.ExpectKeyFetchSuccess(false);
171
172  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
173      .WillRepeatedly(Return(tmpfile_));
174  EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
175      .WillOnce(Return(false))
176      .RetiresOnSaturation();
177
178  MockKeyUser delegate(OwnerManager::KEY_UNAVAILABLE);
179  service_->StartVerifyAttempt("", std::vector<uint8>(), &delegate);
180
181  message_loop_.Run();
182}
183
184TEST_F(OwnershipServiceTest, GetKeyAndVerify) {
185  MockKeyLoadObserver loader;
186  loader.ExpectKeyFetchSuccess(true);
187  loader.SetQuitOnKeyFetch(false);
188
189  std::string data;
190  std::vector<uint8> sig(0, 2);
191
192  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
193      .WillRepeatedly(Return(tmpfile_));
194  EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
195      .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
196                      Return(true)))
197      .RetiresOnSaturation();
198  EXPECT_CALL(*mock_, Verify(Eq(data), Eq(sig), Eq(fake_public_key_)))
199      .WillOnce(Return(true))
200      .RetiresOnSaturation();
201
202  MockKeyUser delegate(OwnerManager::SUCCESS);
203  service_->StartVerifyAttempt(data, sig, &delegate);
204
205  message_loop_.Run();
206}
207
208TEST_F(OwnershipServiceTest, GetKeyAndFailVerify) {
209  MockKeyLoadObserver loader;
210  loader.ExpectKeyFetchSuccess(true);
211  loader.SetQuitOnKeyFetch(false);
212
213  std::string data;
214  std::vector<uint8> sig(0, 2);
215
216  EXPECT_CALL(*mock_, GetOwnerKeyFilePath())
217      .WillRepeatedly(Return(tmpfile_));
218  EXPECT_CALL(*mock_, ImportPublicKey(tmpfile_, _))
219      .WillOnce(DoAll(SetArgumentPointee<1>(fake_public_key_),
220                      Return(true)))
221      .RetiresOnSaturation();
222  EXPECT_CALL(*mock_, Verify(Eq(data), Eq(sig), Eq(fake_public_key_)))
223      .WillOnce(Return(false))
224      .RetiresOnSaturation();
225
226  MockKeyUser delegate(OwnerManager::OPERATION_FAILED);
227  service_->StartVerifyAttempt(data, sig, &delegate);
228
229  message_loop_.Run();
230}
231
232}  // namespace chromeos
233