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: 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 } 40 virtual ~OwnerManagerTest() {} 41 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 55 virtual void TearDown() { 56 OwnerKeyUtils::set_factory(NULL); 57 } 58 59 void StartUnowned() { 60 file_util::Delete(tmpfile_, false); 61 } 62 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 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 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 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 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 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 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 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 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