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/login/parallel_authenticator.h" | 5 #include "chrome/browser/chromeos/login/parallel_authenticator.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/file_path.h" | 11 #include "base/file_path.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/rand_util.h" | 15 #include "base/rand_util.h" |
| 16 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
| 17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
| 18 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
| 19 #include "chrome/browser/chromeos/cros/cert_library.h" | |
| 19 #include "chrome/browser/chromeos/cros/cryptohome_library.h" | 20 #include "chrome/browser/chromeos/cros/cryptohome_library.h" |
| 20 #include "chrome/browser/chromeos/login/auth_response_handler.h" | 21 #include "chrome/browser/chromeos/login/auth_response_handler.h" |
| 21 #include "chrome/browser/chromeos/login/authentication_notification_details.h" | 22 #include "chrome/browser/chromeos/login/authentication_notification_details.h" |
| 22 #include "chrome/browser/chromeos/login/login_status_consumer.h" | 23 #include "chrome/browser/chromeos/login/login_status_consumer.h" |
| 23 #include "chrome/browser/chromeos/login/ownership_service.h" | 24 #include "chrome/browser/chromeos/login/ownership_service.h" |
| 24 #include "chrome/browser/chromeos/login/user_manager.h" | 25 #include "chrome/browser/chromeos/login/user_manager.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/browser/profiles/profile_manager.h" | 27 #include "chrome/browser/profiles/profile_manager.h" |
| 27 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 28 #include "chrome/common/chrome_paths.h" | 29 #include "chrome/common/chrome_paths.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 39 #include "net/url_request/url_request_status.h" | 40 #include "net/url_request/url_request_status.h" |
| 40 #include "third_party/libjingle/source/talk/base/urlencode.h" | 41 #include "third_party/libjingle/source/talk/base/urlencode.h" |
| 41 | 42 |
| 42 using base::Time; | 43 using base::Time; |
| 43 using base::TimeDelta; | 44 using base::TimeDelta; |
| 44 using file_util::GetFileSize; | 45 using file_util::GetFileSize; |
| 45 using file_util::PathExists; | 46 using file_util::PathExists; |
| 46 using file_util::ReadFile; | 47 using file_util::ReadFile; |
| 47 using file_util::ReadFileToString; | 48 using file_util::ReadFileToString; |
| 48 | 49 |
| 50 namespace { | |
| 51 | |
| 52 const int kPassHashLen = 32; | |
| 53 const size_t kKeySize = 16; | |
| 54 | |
| 55 std::string DecryptTokenWithKey( | |
|
wtc
2011/09/06 21:35:17
Nit: as recommended by the Style Guide, it'd be ni
zel
2011/09/06 22:33:35
Done.
| |
| 56 crypto::SymmetricKey* key, | |
| 57 const std::string& salt, | |
| 58 const std::string& encrypted_token_hex) { | |
| 59 std::vector<uint8> encrypted_token_bytes; | |
| 60 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) | |
| 61 return std::string(); | |
| 62 | |
| 63 std::string encrypted_token( | |
| 64 reinterpret_cast<char*>(encrypted_token_bytes.data()), | |
| 65 encrypted_token_bytes.size()); | |
| 66 crypto::Encryptor encryptor; | |
| 67 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) | |
| 68 return std::string(); | |
| 69 | |
| 70 std::string nonce = salt.substr(0, kKeySize); | |
| 71 std::string token; | |
| 72 CHECK(encryptor.SetCounter(nonce)); | |
| 73 if (!encryptor.Decrypt(encrypted_token, &token)) | |
| 74 return std::string(); | |
| 75 return token; | |
| 76 } | |
| 77 | |
| 78 } // namespace | |
| 79 | |
| 49 namespace chromeos { | 80 namespace chromeos { |
| 50 | 81 |
| 51 // static | 82 // static |
| 52 const char ParallelAuthenticator::kLocalaccountFile[] = "localaccount"; | 83 const char ParallelAuthenticator::kLocalaccountFile[] = "localaccount"; |
| 53 | 84 |
| 54 // static | 85 // static |
| 55 const int ParallelAuthenticator::kClientLoginTimeoutMs = 10000; | 86 const int ParallelAuthenticator::kClientLoginTimeoutMs = 10000; |
| 56 // static | 87 // static |
| 57 const int ParallelAuthenticator::kLocalaccountRetryIntervalMs = 20; | 88 const int ParallelAuthenticator::kLocalaccountRetryIntervalMs = 20; |
| 58 | 89 |
| 59 const int kPassHashLen = 32; | |
| 60 const size_t kKeySize = 16; | |
| 61 | |
| 62 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) | 90 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) |
| 63 : Authenticator(consumer), | 91 : Authenticator(consumer), |
| 64 already_reported_success_(false), | 92 already_reported_success_(false), |
| 65 checked_for_localaccount_(false), | 93 checked_for_localaccount_(false), |
| 66 using_oauth_( | 94 using_oauth_( |
| 67 CommandLine::ForCurrentProcess()->HasSwitch( | 95 CommandLine::ForCurrentProcess()->HasSwitch( |
| 68 switches::kWebUILogin) && | 96 switches::kWebUILogin) && |
| 69 !CommandLine::ForCurrentProcess()->HasSwitch( | 97 !CommandLine::ForCurrentProcess()->HasSwitch( |
| 70 switches::kSkipOAuthLogin)) { | 98 switches::kSkipOAuthLogin)) { |
| 71 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded()); | 99 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded()); |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 655 } | 683 } |
| 656 | 684 |
| 657 void ParallelAuthenticator::LoadSystemSalt() { | 685 void ParallelAuthenticator::LoadSystemSalt() { |
| 658 if (!system_salt_.empty()) | 686 if (!system_salt_.empty()) |
| 659 return; | 687 return; |
| 660 system_salt_ = CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(); | 688 system_salt_ = CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(); |
| 661 CHECK(!system_salt_.empty()); | 689 CHECK(!system_salt_.empty()); |
| 662 CHECK_EQ(system_salt_.size() % 2, 0U); | 690 CHECK_EQ(system_salt_.size() % 2, 0U); |
| 663 } | 691 } |
| 664 | 692 |
| 693 bool ParallelAuthenticator::LoadSupplementalUserKey() { | |
| 694 if (!supplemental_user_key_.get()) { | |
| 695 supplemental_user_key_.reset( | |
| 696 CrosLibrary::Get()->GetCertLibrary()->GetSupplementalUserKey()); | |
| 697 } | |
| 698 return supplemental_user_key_.get() != NULL; | |
| 699 } | |
| 700 | |
| 701 | |
| 665 void ParallelAuthenticator::LoadLocalaccount(const std::string& filename) { | 702 void ParallelAuthenticator::LoadLocalaccount(const std::string& filename) { |
| 666 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 703 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 667 { | 704 { |
| 668 base::AutoLock for_this_block(localaccount_lock_); | 705 base::AutoLock for_this_block(localaccount_lock_); |
| 669 if (checked_for_localaccount_) | 706 if (checked_for_localaccount_) |
| 670 return; | 707 return; |
| 671 } | 708 } |
| 672 FilePath localaccount_file; | 709 FilePath localaccount_file; |
| 673 std::string localaccount; | 710 std::string localaccount; |
| 674 if (PathService::Get(base::DIR_EXE, &localaccount_file)) { | 711 if (PathService::Get(base::DIR_EXE, &localaccount_file)) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 686 | 723 |
| 687 void ParallelAuthenticator::SetLocalaccount(const std::string& new_name) { | 724 void ParallelAuthenticator::SetLocalaccount(const std::string& new_name) { |
| 688 localaccount_ = new_name; | 725 localaccount_ = new_name; |
| 689 { // extra braces for clarity about AutoLock scope. | 726 { // extra braces for clarity about AutoLock scope. |
| 690 base::AutoLock for_this_block(localaccount_lock_); | 727 base::AutoLock for_this_block(localaccount_lock_); |
| 691 checked_for_localaccount_ = true; | 728 checked_for_localaccount_ = true; |
| 692 } | 729 } |
| 693 } | 730 } |
| 694 | 731 |
| 695 std::string ParallelAuthenticator::EncryptToken(const std::string& token) { | 732 std::string ParallelAuthenticator::EncryptToken(const std::string& token) { |
| 696 // TODO(zelidrag): Replace salt with | 733 if (!LoadSupplementalUserKey()) |
| 697 scoped_ptr<crypto::SymmetricKey> key( | 734 return std::string(); |
| 698 crypto::SymmetricKey::DeriveKeyFromPassword( | |
| 699 crypto::SymmetricKey::AES, UserSupplementalKeyAsAscii(), | |
| 700 SaltAsAscii(), 1000, 256)); | |
| 701 crypto::Encryptor encryptor; | 735 crypto::Encryptor encryptor; |
| 702 if (!encryptor.Init(key.get(), crypto::Encryptor::CTR, std::string())) | 736 if (!encryptor.Init(supplemental_user_key_.get(), crypto::Encryptor::CTR, |
| 737 std::string())) | |
| 703 return std::string(); | 738 return std::string(); |
| 704 | 739 |
| 705 std::string nonce = SaltAsAscii().substr(0, kKeySize); | 740 std::string nonce = SaltAsAscii().substr(0, kKeySize); |
| 706 std::string encoded_token; | 741 std::string encoded_token; |
| 707 CHECK(encryptor.SetCounter(nonce)); | 742 CHECK(encryptor.SetCounter(nonce)); |
| 708 if (!encryptor.Encrypt(token, &encoded_token)) | 743 if (!encryptor.Encrypt(token, &encoded_token)) |
| 709 return std::string(); | 744 return std::string(); |
| 710 | 745 |
| 711 return StringToLowerASCII(base::HexEncode( | 746 return StringToLowerASCII(base::HexEncode( |
| 712 reinterpret_cast<const void*>(encoded_token.data()), | 747 reinterpret_cast<const void*>(encoded_token.data()), |
| 713 encoded_token.size())); | 748 encoded_token.size())); |
| 714 } | 749 } |
| 715 | |
| 716 std::string ParallelAuthenticator::DecryptToken( | 750 std::string ParallelAuthenticator::DecryptToken( |
| 717 const std::string& encrypted_token_hex) { | 751 const std::string& encrypted_token_hex) { |
| 718 std::vector<uint8> encrypted_token_bytes; | 752 if (!LoadSupplementalUserKey()) |
| 719 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) | |
| 720 return std::string(); | 753 return std::string(); |
| 754 return DecryptTokenWithKey(supplemental_user_key_.get(), | |
| 755 SaltAsAscii(), | |
| 756 encrypted_token_hex); | |
| 757 } | |
| 721 | 758 |
| 722 std::string encrypted_token( | 759 std::string ParallelAuthenticator::DecryptLegacyToken( |
| 723 reinterpret_cast<char*>(encrypted_token_bytes.data()), | 760 const std::string& encrypted_token_hex) { |
| 724 encrypted_token_bytes.size()); | |
| 725 scoped_ptr<crypto::SymmetricKey> key( | 761 scoped_ptr<crypto::SymmetricKey> key( |
| 726 crypto::SymmetricKey::DeriveKeyFromPassword( | 762 crypto::SymmetricKey::DeriveKeyFromPassword( |
| 727 crypto::SymmetricKey::AES, UserSupplementalKeyAsAscii(), | 763 crypto::SymmetricKey::AES, UserSupplementalKeyAsAscii(), |
| 728 SaltAsAscii(), 1000, 256)); | 764 SaltAsAscii(), 1000, 256)); |
| 729 crypto::Encryptor encryptor; | 765 return DecryptTokenWithKey(key.get(), SaltAsAscii(), encrypted_token_hex); |
| 730 if (!encryptor.Init(key.get(), crypto::Encryptor::CTR, std::string())) | |
| 731 return std::string(); | |
| 732 | |
| 733 std::string nonce = SaltAsAscii().substr(0, kKeySize); | |
| 734 std::string token; | |
| 735 CHECK(encryptor.SetCounter(nonce)); | |
| 736 if (!encryptor.Decrypt(encrypted_token, &token)) | |
| 737 return std::string(); | |
| 738 return token; | |
| 739 } | 766 } |
| 740 | 767 |
| 741 | |
| 742 std::string ParallelAuthenticator::HashPassword(const std::string& password) { | 768 std::string ParallelAuthenticator::HashPassword(const std::string& password) { |
| 743 // Get salt, ascii encode, update sha with that, then update with ascii | 769 // Get salt, ascii encode, update sha with that, then update with ascii |
| 744 // of password, then end. | 770 // of password, then end. |
| 745 std::string ascii_salt = SaltAsAscii(); | 771 std::string ascii_salt = SaltAsAscii(); |
| 746 char passhash_buf[kPassHashLen]; | 772 char passhash_buf[kPassHashLen]; |
| 747 | 773 |
| 748 // Hash salt and password | 774 // Hash salt and password |
| 749 crypto::SHA256HashString(ascii_salt + password, | 775 crypto::SHA256HashString(ascii_salt + password, |
| 750 &passhash_buf, sizeof(passhash_buf)); | 776 &passhash_buf, sizeof(passhash_buf)); |
| 751 | 777 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 768 } | 794 } |
| 769 | 795 |
| 770 void ParallelAuthenticator::ResolveLoginCompletionStatus() { | 796 void ParallelAuthenticator::ResolveLoginCompletionStatus() { |
| 771 // Shortcut online state resolution process. | 797 // Shortcut online state resolution process. |
| 772 current_state_->RecordOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), | 798 current_state_->RecordOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), |
| 773 LoginFailure::None()); | 799 LoginFailure::None()); |
| 774 Resolve(); | 800 Resolve(); |
| 775 } | 801 } |
| 776 | 802 |
| 777 } // namespace chromeos | 803 } // namespace chromeos |
| OLD | NEW |