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 |