Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/cros/cryptohome_library.h" | 5 #include "chrome/browser/chromeos/cros/cryptohome_library.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/hash_tables.h" | 9 #include "base/hash_tables.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/string_number_conversions.h" | |
| 12 #include "base/string_util.h" | |
| 11 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 12 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
| 13 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "crypto/encryptor.h" | |
| 17 #include "crypto/sha2.h" | |
| 14 | 18 |
| 15 using content::BrowserThread; | 19 using content::BrowserThread; |
| 16 | 20 |
| 17 namespace { | 21 namespace { |
| 18 const char kStubSystemSalt[] = "stub_system_salt"; | 22 |
| 23 const char kStubSystemSalt[] = "stub_system_salt"; | |
| 24 const int kPassHashLen = 32; | |
| 25 const size_t kKeySize = 16; | |
| 26 | |
| 27 // Decrypts (AES) hex encoded encrypted token given |key| and |salt|. | |
| 28 std::string DecryptTokenWithKey( | |
|
Nikita (slow)
2011/12/01 14:34:13
DecryptTokenWithKey() should be moved to some comm
zel
2011/12/02 02:35:23
CryptohomeLibrary does not need to have this one.
| |
| 29 crypto::SymmetricKey* key, | |
| 30 const std::string& salt, | |
| 31 const std::string& encrypted_token_hex) { | |
| 32 std::vector<uint8> encrypted_token_bytes; | |
| 33 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) | |
| 34 return std::string(); | |
| 35 | |
| 36 std::string encrypted_token( | |
| 37 reinterpret_cast<char*>(encrypted_token_bytes.data()), | |
| 38 encrypted_token_bytes.size()); | |
| 39 crypto::Encryptor encryptor; | |
| 40 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) | |
| 41 return std::string(); | |
| 42 | |
| 43 std::string nonce = salt.substr(0, kKeySize); | |
| 44 std::string token; | |
| 45 CHECK(encryptor.SetCounter(nonce)); | |
| 46 if (!encryptor.Decrypt(encrypted_token, &token)) | |
| 47 return std::string(); | |
| 48 return token; | |
| 49 } | |
| 50 | |
| 19 } | 51 } |
| 20 | 52 |
| 21 namespace chromeos { | 53 namespace chromeos { |
| 22 | 54 |
| 23 // This class handles the interaction with the ChromeOS cryptohome library APIs. | 55 // This class handles the interaction with the ChromeOS cryptohome library APIs. |
| 24 class CryptohomeLibraryImpl : public CryptohomeLibrary { | 56 class CryptohomeLibraryImpl : public CryptohomeLibrary { |
| 25 public: | 57 public: |
| 26 CryptohomeLibraryImpl() {} | 58 CryptohomeLibraryImpl() {} |
| 27 virtual ~CryptohomeLibraryImpl() {} | 59 virtual ~CryptohomeLibraryImpl() {} |
| 28 | 60 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 return CacheCallback( | 109 return CacheCallback( |
| 78 chromeos::CryptohomeAsyncRemove(user_email.c_str()), | 110 chromeos::CryptohomeAsyncRemove(user_email.c_str()), |
| 79 d, | 111 d, |
| 80 "Couldn't initiate async removal of cryptohome."); | 112 "Couldn't initiate async removal of cryptohome."); |
| 81 } | 113 } |
| 82 | 114 |
| 83 virtual bool IsMounted() OVERRIDE { | 115 virtual bool IsMounted() OVERRIDE { |
| 84 return chromeos::CryptohomeIsMounted(); | 116 return chromeos::CryptohomeIsMounted(); |
| 85 } | 117 } |
| 86 | 118 |
| 87 virtual CryptohomeBlob GetSystemSalt() OVERRIDE { | |
| 88 CryptohomeBlob system_salt; | |
| 89 char* salt_buf; | |
| 90 int salt_len; | |
| 91 bool result = chromeos::CryptohomeGetSystemSaltSafe(&salt_buf, &salt_len); | |
| 92 if (result) { | |
| 93 system_salt.resize(salt_len); | |
| 94 if ((int)system_salt.size() == salt_len) { | |
| 95 memcpy(&system_salt[0], static_cast<const void*>(salt_buf), | |
| 96 salt_len); | |
| 97 } else { | |
| 98 system_salt.clear(); | |
| 99 } | |
| 100 } | |
| 101 return system_salt; | |
| 102 } | |
| 103 | |
| 104 virtual bool AsyncSetOwnerUser( | 119 virtual bool AsyncSetOwnerUser( |
| 105 const std::string& username, Delegate* d) OVERRIDE { | 120 const std::string& username, Delegate* d) OVERRIDE { |
| 106 return CacheCallback( | 121 return CacheCallback( |
| 107 chromeos::CryptohomeAsyncSetOwnerUser(username.c_str()), | 122 chromeos::CryptohomeAsyncSetOwnerUser(username.c_str()), |
| 108 d, | 123 d, |
| 109 "Couldn't do set owner user in Cryptohomed."); | 124 "Couldn't do set owner user in Cryptohomed."); |
| 110 } | 125 } |
| 111 | 126 |
| 112 virtual bool TpmIsReady() OVERRIDE { | 127 virtual bool TpmIsReady() OVERRIDE { |
| 113 return chromeos::CryptohomeTpmIsReady(); | 128 return chromeos::CryptohomeTpmIsReady(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 | 192 |
| 178 virtual void Pkcs11GetTpmTokenInfo( | 193 virtual void Pkcs11GetTpmTokenInfo( |
| 179 std::string* label, std::string* user_pin) OVERRIDE { | 194 std::string* label, std::string* user_pin) OVERRIDE { |
| 180 chromeos::CryptohomePkcs11GetTpmTokenInfo(label, user_pin); | 195 chromeos::CryptohomePkcs11GetTpmTokenInfo(label, user_pin); |
| 181 } | 196 } |
| 182 | 197 |
| 183 virtual bool Pkcs11IsTpmTokenReady() OVERRIDE { | 198 virtual bool Pkcs11IsTpmTokenReady() OVERRIDE { |
| 184 return chromeos::CryptohomePkcs11IsTpmTokenReady(); | 199 return chromeos::CryptohomePkcs11IsTpmTokenReady(); |
| 185 } | 200 } |
| 186 | 201 |
| 202 virtual std::string HashPassword(const std::string& password) OVERRIDE { | |
| 203 // Get salt, ascii encode, update sha with that, then update with ascii | |
| 204 // of password, then end. | |
| 205 std::string ascii_salt = GetSystemSalt(); | |
| 206 char passhash_buf[kPassHashLen]; | |
| 207 | |
| 208 // Hash salt and password | |
| 209 crypto::SHA256HashString(ascii_salt + password, | |
| 210 &passhash_buf, sizeof(passhash_buf)); | |
| 211 | |
| 212 return StringToLowerASCII(base::HexEncode( | |
| 213 reinterpret_cast<const void*>(passhash_buf), | |
| 214 sizeof(passhash_buf) / 2)); | |
| 215 } | |
| 216 | |
| 217 virtual std::string GetSystemSalt() OVERRIDE { | |
| 218 LoadSystemSalt(); // no-op if it's already loaded. | |
| 219 return StringToLowerASCII(base::HexEncode( | |
| 220 reinterpret_cast<const void*>(system_salt_.data()), | |
| 221 system_salt_.size())); | |
| 222 } | |
| 223 | |
| 187 private: | 224 private: |
| 225 typedef base::hash_map<int, Delegate*> CallbackMap; | |
| 226 | |
| 188 static void Handler(const chromeos::CryptohomeAsyncCallStatus& event, | 227 static void Handler(const chromeos::CryptohomeAsyncCallStatus& event, |
| 189 void* cryptohome_library) { | 228 void* cryptohome_library) { |
| 190 CryptohomeLibraryImpl* library = | 229 CryptohomeLibraryImpl* library = |
| 191 reinterpret_cast<CryptohomeLibraryImpl*>(cryptohome_library); | 230 reinterpret_cast<CryptohomeLibraryImpl*>(cryptohome_library); |
| 192 library->Dispatch(event); | 231 library->Dispatch(event); |
| 193 } | 232 } |
| 194 | 233 |
| 195 void Dispatch(const chromeos::CryptohomeAsyncCallStatus& event) { | 234 void Dispatch(const chromeos::CryptohomeAsyncCallStatus& event) { |
| 196 const CallbackMap::iterator callback = callback_map_.find(event.async_id); | 235 const CallbackMap::iterator callback = callback_map_.find(event.async_id); |
| 197 if (callback == callback_map_.end()) { | 236 if (callback == callback_map_.end()) { |
| 198 LOG(ERROR) << "Received signal for unknown async_id " << event.async_id; | 237 LOG(ERROR) << "Received signal for unknown async_id " << event.async_id; |
| 199 return; | 238 return; |
| 200 } | 239 } |
| 201 if (callback->second) | 240 if (callback->second) |
| 202 callback->second->OnComplete(event.return_status, event.return_code); | 241 callback->second->OnComplete(event.return_status, event.return_code); |
| 203 callback_map_.erase(callback); | 242 callback_map_.erase(callback); |
| 204 } | 243 } |
| 205 | 244 |
| 206 bool CacheCallback(int async_id, Delegate* d, const char* error) { | 245 bool CacheCallback(int async_id, Delegate* d, const char* error) { |
| 207 if (async_id == 0) { | 246 if (async_id == 0) { |
| 208 LOG(ERROR) << error; | 247 LOG(ERROR) << error; |
| 209 return false; | 248 return false; |
| 210 } | 249 } |
| 211 VLOG(1) << "Adding handler for " << async_id; | 250 VLOG(1) << "Adding handler for " << async_id; |
| 212 callback_map_[async_id] = d; | 251 callback_map_[async_id] = d; |
| 213 return true; | 252 return true; |
| 214 } | 253 } |
| 215 | 254 |
| 216 typedef base::hash_map<int, Delegate*> CallbackMap; | 255 void LoadSystemSalt() { |
| 256 if (!system_salt_.empty()) | |
| 257 return; | |
| 258 | |
| 259 char* salt_buf; | |
| 260 int salt_len; | |
| 261 bool result = chromeos::CryptohomeGetSystemSaltSafe(&salt_buf, &salt_len); | |
| 262 if (result) { | |
| 263 system_salt_.resize(salt_len); | |
| 264 if (static_cast<int>(system_salt_.size()) == salt_len) | |
| 265 memcpy(&system_salt_[0], static_cast<const void*>(salt_buf), salt_len); | |
| 266 else | |
| 267 system_salt_.clear(); | |
| 268 } | |
| 269 CHECK(!system_salt_.empty()); | |
| 270 CHECK_EQ(system_salt_.size() % 2, 0U); | |
| 271 } | |
| 272 | |
| 273 chromeos::CryptohomeBlob system_salt_; | |
| 217 mutable CallbackMap callback_map_; | 274 mutable CallbackMap callback_map_; |
| 218 | 275 |
| 219 void* cryptohome_connection_; | 276 void* cryptohome_connection_; |
| 220 | 277 |
| 221 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); | 278 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryImpl); |
| 222 }; | 279 }; |
| 223 | 280 |
| 224 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { | 281 class CryptohomeLibraryStubImpl : public CryptohomeLibrary { |
| 225 public: | 282 public: |
| 226 CryptohomeLibraryStubImpl() | 283 CryptohomeLibraryStubImpl() |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 270 BrowserThread::PostTask( | 327 BrowserThread::PostTask( |
| 271 BrowserThread::UI, FROM_HERE, | 328 BrowserThread::UI, FROM_HERE, |
| 272 base::Bind(&DoStubCallback, callback)); | 329 base::Bind(&DoStubCallback, callback)); |
| 273 return true; | 330 return true; |
| 274 } | 331 } |
| 275 | 332 |
| 276 virtual bool IsMounted() OVERRIDE { | 333 virtual bool IsMounted() OVERRIDE { |
| 277 return true; | 334 return true; |
| 278 } | 335 } |
| 279 | 336 |
| 280 virtual CryptohomeBlob GetSystemSalt() OVERRIDE { | |
| 281 CryptohomeBlob salt = CryptohomeBlob(); | |
| 282 for (size_t i = 0; i < strlen(kStubSystemSalt); i++) | |
| 283 salt.push_back(static_cast<unsigned char>(kStubSystemSalt[i])); | |
| 284 | |
| 285 return salt; | |
| 286 } | |
| 287 | |
| 288 virtual bool AsyncSetOwnerUser( | 337 virtual bool AsyncSetOwnerUser( |
| 289 const std::string& username, Delegate* callback) OVERRIDE { | 338 const std::string& username, Delegate* callback) OVERRIDE { |
| 290 BrowserThread::PostTask( | 339 BrowserThread::PostTask( |
| 291 BrowserThread::UI, FROM_HERE, | 340 BrowserThread::UI, FROM_HERE, |
| 292 base::Bind(&DoStubCallback, callback)); | 341 base::Bind(&DoStubCallback, callback)); |
| 293 return true; | 342 return true; |
| 294 } | 343 } |
| 295 | 344 |
| 296 // Tpm begin ready after 20-th call. | 345 // Tpm begin ready after 20-th call. |
| 297 virtual bool TpmIsReady() OVERRIDE { | 346 virtual bool TpmIsReady() OVERRIDE { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 } | 402 } |
| 354 | 403 |
| 355 virtual void Pkcs11GetTpmTokenInfo(std::string* label, | 404 virtual void Pkcs11GetTpmTokenInfo(std::string* label, |
| 356 std::string* user_pin) OVERRIDE { | 405 std::string* user_pin) OVERRIDE { |
| 357 *label = "Stub TPM Token"; | 406 *label = "Stub TPM Token"; |
| 358 *user_pin = "012345"; | 407 *user_pin = "012345"; |
| 359 } | 408 } |
| 360 | 409 |
| 361 virtual bool Pkcs11IsTpmTokenReady() OVERRIDE { return true; } | 410 virtual bool Pkcs11IsTpmTokenReady() OVERRIDE { return true; } |
| 362 | 411 |
| 412 virtual std::string HashPassword(const std::string& password) OVERRIDE { | |
| 413 return StringToLowerASCII(base::HexEncode( | |
| 414 reinterpret_cast<const void*>(password.data()), | |
| 415 password.length())); | |
| 416 } | |
| 417 | |
| 418 virtual std::string GetSystemSalt() OVERRIDE { | |
| 419 return kStubSystemSalt; | |
| 420 } | |
| 421 | |
| 363 private: | 422 private: |
| 364 static void DoStubCallback(Delegate* callback) { | 423 static void DoStubCallback(Delegate* callback) { |
| 365 if (callback) | 424 if (callback) |
| 366 callback->OnComplete(true, kCryptohomeMountErrorNone); | 425 callback->OnComplete(true, kCryptohomeMountErrorNone); |
| 367 } | 426 } |
| 368 | 427 |
| 369 std::map<std::string, std::string> install_attrs_; | 428 std::map<std::string, std::string> install_attrs_; |
| 370 bool locked_; | 429 bool locked_; |
| 371 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl); | 430 DISALLOW_COPY_AND_ASSIGN(CryptohomeLibraryStubImpl); |
| 372 }; | 431 }; |
| 373 | 432 |
| 374 CryptohomeLibrary::CryptohomeLibrary() {} | 433 CryptohomeLibrary::CryptohomeLibrary() {} |
| 375 CryptohomeLibrary::~CryptohomeLibrary() {} | 434 CryptohomeLibrary::~CryptohomeLibrary() {} |
| 376 | 435 |
| 377 // static | 436 // static |
| 378 CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) { | 437 CryptohomeLibrary* CryptohomeLibrary::GetImpl(bool stub) { |
| 379 CryptohomeLibrary* impl; | 438 CryptohomeLibrary* impl; |
| 380 if (stub) | 439 if (stub) |
| 381 impl = new CryptohomeLibraryStubImpl(); | 440 impl = new CryptohomeLibraryStubImpl(); |
| 382 else | 441 else |
| 383 impl = new CryptohomeLibraryImpl(); | 442 impl = new CryptohomeLibraryImpl(); |
| 384 impl->Init(); | 443 impl->Init(); |
| 385 return impl; | 444 return impl; |
| 386 } | 445 } |
| 387 | 446 |
| 388 } // namespace chromeos | 447 } // namespace chromeos |
| OLD | NEW |