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: 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 83 TEST_F(OwnershipServiceTest, IsOwned) { 84 EXPECT_CALL(*mock_, GetOwnerKeyFilePath()) 85 .WillRepeatedly(Return(tmpfile_)); 86 EXPECT_TRUE(service_->IsAlreadyOwned()); 87 } 88 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 95 TEST_F(OwnershipServiceTest, IsUnowned) { 96 StartUnowned(); 97 98 EXPECT_CALL(*mock_, GetOwnerKeyFilePath()) 99 .WillRepeatedly(Return(tmpfile_)); 100 EXPECT_FALSE(service_->IsAlreadyOwned()); 101 } 102 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 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 125 TEST_F(OwnershipServiceTest, UpdateOwnerKey) { 126 MockKeyUpdateUser delegate; 127 service_->StartUpdateOwnerKey(std::vector<uint8>(), &delegate); 128 129 message_loop_.Run(); 130 } 131 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 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 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 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 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