Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: chrome/browser/chromeos/cros/cert_library.cc

Issue 14179007: Move cryptohome_library to src/chromeos (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/cert_library.h" 5 #include "chrome/browser/chromeos/cros/cert_library.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/chromeos/chromeos_version.h" 9 #include "base/chromeos/chromeos_version.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
12 #include "base/observer_list_threadsafe.h" 12 #include "base/observer_list_threadsafe.h"
13 #include "base/string_util.h" 13 #include "base/string_util.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/browser_process.h" // g_browser_process 16 #include "chrome/browser/browser_process.h" // g_browser_process
17 #include "chrome/browser/chromeos/cros/cros_library.h"
18 #include "chrome/browser/chromeos/cros/cryptohome_library.h"
19 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/net/x509_certificate_model.h" 18 #include "chrome/common/net/x509_certificate_model.h"
21 #include "chromeos/dbus/cryptohome_client.h" 19 #include "chromeos/dbus/cryptohome_client.h"
22 #include "chromeos/dbus/dbus_thread_manager.h" 20 #include "chromeos/dbus/dbus_thread_manager.h"
23 #include "chromeos/login/login_state.h" 21 #include "chromeos/login/login_state.h"
24 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
25 #include "crypto/encryptor.h"
26 #include "crypto/nss_util.h" 23 #include "crypto/nss_util.h"
27 #include "crypto/sha2.h"
28 #include "crypto/symmetric_key.h"
29 #include "grit/generated_resources.h" 24 #include "grit/generated_resources.h"
30 #include "net/cert/cert_database.h" 25 #include "net/cert/cert_database.h"
31 #include "net/cert/nss_cert_database.h" 26 #include "net/cert/nss_cert_database.h"
32 #include "third_party/icu/public/i18n/unicode/coll.h" // icu::Collator 27 #include "third_party/icu/public/i18n/unicode/coll.h" // icu::Collator
33 #include "ui/base/l10n/l10n_util.h" 28 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/l10n/l10n_util_collator.h" 29 #include "ui/base/l10n/l10n_util_collator.h"
35 30
36 using content::BrowserThread; 31 using content::BrowserThread;
37 32
38 namespace chromeos { 33 namespace chromeos {
39 34
40 namespace { 35 namespace {
41 36
42 // Root CA certificates that are built into Chrome use this token name. 37 // Root CA certificates that are built into Chrome use this token name.
43 const char kRootCertificateTokenName[] = "Builtin Object Token"; 38 const char kRootCertificateTokenName[] = "Builtin Object Token";
44 39
45 // Delay between certificate requests while waiting for TPM/PKCS#11 init. 40 // Delay between certificate requests while waiting for TPM/PKCS#11 init.
46 const int kRequestDelayMs = 500; 41 const int kRequestDelayMs = 500;
47 42
48 const size_t kKeySize = 16;
49
50 string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) { 43 string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) {
51 std::string org; 44 std::string org;
52 if (!cert->subject().organization_names.empty()) 45 if (!cert->subject().organization_names.empty())
53 org = cert->subject().organization_names[0]; 46 org = cert->subject().organization_names[0];
54 if (org.empty()) 47 if (org.empty())
55 org = cert->subject().GetDisplayName(); 48 org = cert->subject().GetDisplayName();
56 string16 issued_by = UTF8ToUTF16( 49 string16 issued_by = UTF8ToUTF16(
57 x509_certificate_model::GetIssuerCommonName(cert->os_cert_handle(), 50 x509_certificate_model::GetIssuerCommonName(cert->os_cert_handle(),
58 org)); // alternative text 51 org)); // alternative text
59 string16 issued_to = UTF8ToUTF16( 52 string16 issued_to = UTF8ToUTF16(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 virtual const CertList& GetServerCertificates() const OVERRIDE { 152 virtual const CertList& GetServerCertificates() const OVERRIDE {
160 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 153 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161 return server_certs_; 154 return server_certs_;
162 } 155 }
163 156
164 virtual const CertList& GetCACertificates() const OVERRIDE { 157 virtual const CertList& GetCACertificates() const OVERRIDE {
165 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 158 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
166 return server_ca_certs_; 159 return server_ca_certs_;
167 } 160 }
168 161
169 virtual crypto::SymmetricKey* PassphraseToKey(const std::string& passprhase,
170 const std::string& salt) {
171 return crypto::SymmetricKey::DeriveKeyFromPassword(
172 crypto::SymmetricKey::AES, passprhase, salt, 1000, 256);
173 }
174
175 virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE {
176 // Don't care about token encryption while debugging.
177 if (!base::chromeos::IsRunningOnChromeOS())
178 return token;
179
180 if (!LoadSystemSaltKey()) {
181 LOG(WARNING) << "System salt key is not available for encrypt.";
182 return std::string();
183 }
184 return EncryptTokenWithKey(
185 system_salt_key_.get(),
186 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
187 token);
188 }
189
190 virtual std::string EncryptWithUserKey(const std::string& token) OVERRIDE {
191 // Don't care about token encryption while debugging.
192 if (!base::chromeos::IsRunningOnChromeOS())
193 return token;
194
195 if (!LoadSupplementalUserKey()) {
196 LOG(WARNING) << "Supplemental user key is not available for encrypt.";
197 return std::string();
198 }
199 return EncryptTokenWithKey(
200 supplemental_user_key_.get(),
201 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
202 token);
203 }
204
205 // Encrypts (AES) the token given |key| and |salt|.
206 virtual std::string EncryptTokenWithKey(crypto::SymmetricKey* key,
207 const std::string& salt,
208 const std::string& token) {
209 crypto::Encryptor encryptor;
210 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
211 LOG(WARNING) << "Failed to initialize Encryptor.";
212 return std::string();
213 }
214 std::string nonce = salt.substr(0, kKeySize);
215 std::string encoded_token;
216 CHECK(encryptor.SetCounter(nonce));
217 if (!encryptor.Encrypt(token, &encoded_token)) {
218 LOG(WARNING) << "Failed to encrypt token.";
219 return std::string();
220 }
221
222 return StringToLowerASCII(base::HexEncode(
223 reinterpret_cast<const void*>(encoded_token.data()),
224 encoded_token.size()));
225 }
226
227 virtual std::string DecryptWithSystemSalt(
228 const std::string& encrypted_token_hex) OVERRIDE {
229 // Don't care about token encryption while debugging.
230 if (!base::chromeos::IsRunningOnChromeOS())
231 return encrypted_token_hex;
232
233 if (!LoadSystemSaltKey()) {
234 LOG(WARNING) << "System salt key is not available for decrypt.";
235 return std::string();
236 }
237 return DecryptTokenWithKey(
238 system_salt_key_.get(),
239 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
240 encrypted_token_hex);
241 }
242
243 virtual std::string DecryptWithUserKey(
244 const std::string& encrypted_token_hex) OVERRIDE {
245 // Don't care about token encryption while debugging.
246 if (!base::chromeos::IsRunningOnChromeOS())
247 return encrypted_token_hex;
248
249 if (!LoadSupplementalUserKey()) {
250 LOG(WARNING) << "Supplemental user key is not available for decrypt.";
251 return std::string();
252 }
253 return DecryptTokenWithKey(
254 supplemental_user_key_.get(),
255 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
256 encrypted_token_hex);
257 }
258
259 // Decrypts (AES) hex encoded encrypted token given |key| and |salt|.
260 virtual std::string DecryptTokenWithKey(
261 crypto::SymmetricKey* key,
262 const std::string& salt,
263 const std::string& encrypted_token_hex) {
264 std::vector<uint8> encrypted_token_bytes;
265 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) {
266 LOG(WARNING) << "Corrupt encrypted token found.";
267 return std::string();
268 }
269
270 std::string encrypted_token(
271 reinterpret_cast<char*>(encrypted_token_bytes.data()),
272 encrypted_token_bytes.size());
273 crypto::Encryptor encryptor;
274 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
275 LOG(WARNING) << "Failed to initialize Encryptor.";
276 return std::string();
277 }
278
279 std::string nonce = salt.substr(0, kKeySize);
280 std::string token;
281 CHECK(encryptor.SetCounter(nonce));
282 if (!encryptor.Decrypt(encrypted_token, &token)) {
283 LOG(WARNING) << "Failed to decrypt token.";
284 return std::string();
285 }
286 return token;
287 }
288
289 // net::CertDatabase::Observer implementation. Observer added on UI thread. 162 // net::CertDatabase::Observer implementation. Observer added on UI thread.
290 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE { 163 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE {
291 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 164 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
292 } 165 }
293 166
294 virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE { 167 virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE {
295 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 168 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
296 // Only load certificates if we have completed an initial request. 169 // Only load certificates if we have completed an initial request.
297 if (certificates_loaded_) { 170 if (certificates_loaded_) {
298 BrowserThread::PostTask( 171 BrowserThread::PostTask(
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 288
416 // Set loaded state and notify observers. 289 // Set loaded state and notify observers.
417 if (!certificates_loaded_) { 290 if (!certificates_loaded_) {
418 certificates_loaded_ = true; 291 certificates_loaded_ = true;
419 NotifyCertificatesLoaded(true); 292 NotifyCertificatesLoaded(true);
420 } else { 293 } else {
421 NotifyCertificatesLoaded(false); 294 NotifyCertificatesLoaded(false);
422 } 295 }
423 } 296 }
424 297
425 bool LoadSupplementalUserKey() {
426 if (!user_logged_in_) {
427 // If we are not logged in, we cannot load any certificates.
428 // Set 'loaded' to true for the UI, since we are not waiting on loading.
429 LOG(WARNING) << "Requesting supplemental use key before login.";
430 return false;
431 }
432 if (!supplemental_user_key_.get()) {
433 supplemental_user_key_.reset(crypto::GetSupplementalUserKey());
434 }
435 return supplemental_user_key_.get() != NULL;
436 }
437
438 // TODO: should this use the system salt for both the password and the salt
439 // value, or should this use a separate salt value?
440 bool LoadSystemSaltKey() {
441 if (!system_salt_key_.get()) {
442 system_salt_key_.reset(PassphraseToKey(
443 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
444 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt()));
445 }
446 return system_salt_key_.get() != NULL;
447 }
448
449 // Call this to start the certificate list initialization process. 298 // Call this to start the certificate list initialization process.
450 // Must be called from the UI thread. 299 // Must be called from the UI thread.
451 void RequestCertificates() { 300 void RequestCertificates() {
452 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 301 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
453 302
454 certificates_requested_ = true; 303 certificates_requested_ = true;
455 304
456 if (!LoginState::Get()->IsUserLoggedIn()) { 305 if (!LoginState::Get()->IsUserLoggedIn()) {
457 // If we are not logged in, we cannot load any certificates. 306 // If we are not logged in, we cannot load any certificates.
458 // Set 'loaded' to true for the UI, since we are not waiting on loading. 307 // Set 'loaded' to true for the UI, since we are not waiting on loading.
459 LOG(WARNING) << "Requesting certificates before login."; 308 LOG(WARNING) << "Requesting certificates before login.";
460 certificates_loaded_ = true; 309 certificates_loaded_ = true;
461 supplemental_user_key_.reset(NULL);
462 return; 310 return;
463 } 311 }
464 312
465 if (!user_logged_in_) { 313 if (!user_logged_in_) {
466 user_logged_in_ = true; 314 user_logged_in_ = true;
467 certificates_loaded_ = false; 315 certificates_loaded_ = false;
468 supplemental_user_key_.reset(NULL);
469 } 316 }
470 317
471 VLOG(1) << "Requesting Certificates."; 318 VLOG(1) << "Requesting Certificates.";
472 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( 319 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled(
473 base::Bind(&CertLibraryImpl::OnTpmIsEnabled, 320 base::Bind(&CertLibraryImpl::OnTpmIsEnabled,
474 weak_ptr_factory_.GetWeakPtr())); 321 weak_ptr_factory_.GetWeakPtr()));
475 } 322 }
476 323
477 // This method is used to implement RequestCertificates. 324 // This method is used to implement RequestCertificates.
478 void OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) { 325 void OnTpmIsEnabled(DBusMethodCallStatus call_status, bool tpm_is_enabled) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 base::Closure request_task_; 410 base::Closure request_task_;
564 411
565 bool tpm_token_ready_; 412 bool tpm_token_ready_;
566 413
567 // Cached TPM token name. 414 // Cached TPM token name.
568 std::string tpm_token_name_; 415 std::string tpm_token_name_;
569 416
570 // Cached TPM user pin. 417 // Cached TPM user pin.
571 std::string tpm_user_pin_; 418 std::string tpm_user_pin_;
572 419
573 // Supplemental user key.
574 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_;
575
576 // A key based on the system salt. Useful for encrypting device-level
577 // data for which we have no additional credentials.
578 scoped_ptr<crypto::SymmetricKey> system_salt_key_;
579
580 // Local state. 420 // Local state.
581 bool user_logged_in_; 421 bool user_logged_in_;
582 bool certificates_requested_; 422 bool certificates_requested_;
583 bool certificates_loaded_; 423 bool certificates_loaded_;
584 // The key store for the current user has been loaded. This flag is needed to 424 // The key store for the current user has been loaded. This flag is needed to
585 // ensure that the key store will not be loaded twice in the policy recovery 425 // ensure that the key store will not be loaded twice in the policy recovery
586 // "safe-mode". 426 // "safe-mode".
587 bool key_store_loaded_; 427 bool key_store_loaded_;
588 428
589 // Certificates. 429 // Certificates.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 } 467 }
628 virtual const CertList& GetUserCertificates() const { 468 virtual const CertList& GetUserCertificates() const {
629 return cert_list_; 469 return cert_list_;
630 } 470 }
631 virtual const CertList& GetServerCertificates() const { 471 virtual const CertList& GetServerCertificates() const {
632 return cert_list_; 472 return cert_list_;
633 } 473 }
634 virtual const CertList& GetCACertificates() const { 474 virtual const CertList& GetCACertificates() const {
635 return cert_list_; 475 return cert_list_;
636 } 476 }
637 virtual std::string EncryptWithSystemSalt(const std::string& token) {
638 return token;
639 }
640 virtual std::string DecryptWithSystemSalt(
641 const std::string& encrypted_token_hex) {
642 return encrypted_token_hex;
643 }
644 virtual std::string EncryptWithUserKey(const std::string& token) {
645 return token;
646 }
647 virtual std::string DecryptWithUserKey(
648 const std::string& encrypted_token_hex) {
649 return encrypted_token_hex;
650 }
651 477
652 private: 478 private:
653 std::string token_name_; 479 std::string token_name_;
654 CertList cert_list_; 480 CertList cert_list_;
655 481
656 DISALLOW_COPY_AND_ASSIGN(CertLibraryImplStub); 482 DISALLOW_COPY_AND_ASSIGN(CertLibraryImplStub);
657 }; 483 };
658 484
659 ////////////////////////////////////////////////////////////////////////////// 485 //////////////////////////////////////////////////////////////////////////////
660 486
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 net::X509Certificate* cert = GetCertificateAt(index); 553 net::X509Certificate* cert = GetCertificateAt(index);
728 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 554 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
729 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); 555 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
730 if (id == pkcs11_id) 556 if (id == pkcs11_id)
731 return index; 557 return index;
732 } 558 }
733 return -1; // Not found. 559 return -1; // Not found.
734 } 560 }
735 561
736 } // chromeos 562 } // chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698