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

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

Powered by Google App Engine
This is Rietveld 408576698