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 // Decrypts (AES) hex encoded encrypted token given |key| and |salt|. |
| 56 std::string DecryptTokenWithKey( |
| 57 crypto::SymmetricKey* key, |
| 58 const std::string& salt, |
| 59 const std::string& encrypted_token_hex) { |
| 60 std::vector<uint8> encrypted_token_bytes; |
| 61 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) |
| 62 return std::string(); |
| 63 |
| 64 std::string encrypted_token( |
| 65 reinterpret_cast<char*>(encrypted_token_bytes.data()), |
| 66 encrypted_token_bytes.size()); |
| 67 crypto::Encryptor encryptor; |
| 68 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) |
| 69 return std::string(); |
| 70 |
| 71 std::string nonce = salt.substr(0, kKeySize); |
| 72 std::string token; |
| 73 CHECK(encryptor.SetCounter(nonce)); |
| 74 if (!encryptor.Decrypt(encrypted_token, &token)) |
| 75 return std::string(); |
| 76 return token; |
| 77 } |
| 78 |
| 79 } // namespace |
| 80 |
49 namespace chromeos { | 81 namespace chromeos { |
50 | 82 |
51 // static | 83 // static |
52 const char ParallelAuthenticator::kLocalaccountFile[] = "localaccount"; | 84 const char ParallelAuthenticator::kLocalaccountFile[] = "localaccount"; |
53 | 85 |
54 // static | 86 // static |
55 const int ParallelAuthenticator::kClientLoginTimeoutMs = 10000; | 87 const int ParallelAuthenticator::kClientLoginTimeoutMs = 10000; |
56 // static | 88 // static |
57 const int ParallelAuthenticator::kLocalaccountRetryIntervalMs = 20; | 89 const int ParallelAuthenticator::kLocalaccountRetryIntervalMs = 20; |
58 | 90 |
59 const int kPassHashLen = 32; | |
60 const size_t kKeySize = 16; | |
61 | |
62 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) | 91 ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer) |
63 : Authenticator(consumer), | 92 : Authenticator(consumer), |
64 already_reported_success_(false), | 93 already_reported_success_(false), |
65 checked_for_localaccount_(false), | 94 checked_for_localaccount_(false), |
66 using_oauth_( | 95 using_oauth_( |
67 CommandLine::ForCurrentProcess()->HasSwitch( | 96 CommandLine::ForCurrentProcess()->HasSwitch( |
68 switches::kWebUILogin) && | 97 switches::kWebUILogin) && |
69 !CommandLine::ForCurrentProcess()->HasSwitch( | 98 !CommandLine::ForCurrentProcess()->HasSwitch( |
70 switches::kSkipOAuthLogin)) { | 99 switches::kSkipOAuthLogin)) { |
71 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded()); | 100 CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded()); |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 } | 695 } |
667 | 696 |
668 void ParallelAuthenticator::LoadSystemSalt() { | 697 void ParallelAuthenticator::LoadSystemSalt() { |
669 if (!system_salt_.empty()) | 698 if (!system_salt_.empty()) |
670 return; | 699 return; |
671 system_salt_ = CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(); | 700 system_salt_ = CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(); |
672 CHECK(!system_salt_.empty()); | 701 CHECK(!system_salt_.empty()); |
673 CHECK_EQ(system_salt_.size() % 2, 0U); | 702 CHECK_EQ(system_salt_.size() % 2, 0U); |
674 } | 703 } |
675 | 704 |
| 705 bool ParallelAuthenticator::LoadSupplementalUserKey() { |
| 706 if (!supplemental_user_key_.get()) { |
| 707 supplemental_user_key_.reset( |
| 708 CrosLibrary::Get()->GetCertLibrary()->GetSupplementalUserKey()); |
| 709 } |
| 710 return supplemental_user_key_.get() != NULL; |
| 711 } |
| 712 |
| 713 |
676 void ParallelAuthenticator::LoadLocalaccount(const std::string& filename) { | 714 void ParallelAuthenticator::LoadLocalaccount(const std::string& filename) { |
677 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
678 { | 716 { |
679 base::AutoLock for_this_block(localaccount_lock_); | 717 base::AutoLock for_this_block(localaccount_lock_); |
680 if (checked_for_localaccount_) | 718 if (checked_for_localaccount_) |
681 return; | 719 return; |
682 } | 720 } |
683 FilePath localaccount_file; | 721 FilePath localaccount_file; |
684 std::string localaccount; | 722 std::string localaccount; |
685 if (PathService::Get(base::DIR_EXE, &localaccount_file)) { | 723 if (PathService::Get(base::DIR_EXE, &localaccount_file)) { |
(...skipping 11 matching lines...) Expand all Loading... |
697 | 735 |
698 void ParallelAuthenticator::SetLocalaccount(const std::string& new_name) { | 736 void ParallelAuthenticator::SetLocalaccount(const std::string& new_name) { |
699 localaccount_ = new_name; | 737 localaccount_ = new_name; |
700 { // extra braces for clarity about AutoLock scope. | 738 { // extra braces for clarity about AutoLock scope. |
701 base::AutoLock for_this_block(localaccount_lock_); | 739 base::AutoLock for_this_block(localaccount_lock_); |
702 checked_for_localaccount_ = true; | 740 checked_for_localaccount_ = true; |
703 } | 741 } |
704 } | 742 } |
705 | 743 |
706 std::string ParallelAuthenticator::EncryptToken(const std::string& token) { | 744 std::string ParallelAuthenticator::EncryptToken(const std::string& token) { |
707 // TODO(zelidrag): Replace salt with | 745 if (!LoadSupplementalUserKey()) |
708 scoped_ptr<crypto::SymmetricKey> key( | 746 return std::string(); |
709 crypto::SymmetricKey::DeriveKeyFromPassword( | |
710 crypto::SymmetricKey::AES, UserSupplementalKeyAsAscii(), | |
711 SaltAsAscii(), 1000, 256)); | |
712 crypto::Encryptor encryptor; | 747 crypto::Encryptor encryptor; |
713 if (!encryptor.Init(key.get(), crypto::Encryptor::CTR, std::string())) | 748 if (!encryptor.Init(supplemental_user_key_.get(), crypto::Encryptor::CTR, |
| 749 std::string())) |
714 return std::string(); | 750 return std::string(); |
715 | 751 |
716 std::string nonce = SaltAsAscii().substr(0, kKeySize); | 752 std::string nonce = SaltAsAscii().substr(0, kKeySize); |
717 std::string encoded_token; | 753 std::string encoded_token; |
718 CHECK(encryptor.SetCounter(nonce)); | 754 CHECK(encryptor.SetCounter(nonce)); |
719 if (!encryptor.Encrypt(token, &encoded_token)) | 755 if (!encryptor.Encrypt(token, &encoded_token)) |
720 return std::string(); | 756 return std::string(); |
721 | 757 |
722 return StringToLowerASCII(base::HexEncode( | 758 return StringToLowerASCII(base::HexEncode( |
723 reinterpret_cast<const void*>(encoded_token.data()), | 759 reinterpret_cast<const void*>(encoded_token.data()), |
724 encoded_token.size())); | 760 encoded_token.size())); |
725 } | 761 } |
726 | |
727 std::string ParallelAuthenticator::DecryptToken( | 762 std::string ParallelAuthenticator::DecryptToken( |
728 const std::string& encrypted_token_hex) { | 763 const std::string& encrypted_token_hex) { |
729 std::vector<uint8> encrypted_token_bytes; | 764 if (!LoadSupplementalUserKey()) |
730 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) | |
731 return std::string(); | 765 return std::string(); |
| 766 return DecryptTokenWithKey(supplemental_user_key_.get(), |
| 767 SaltAsAscii(), |
| 768 encrypted_token_hex); |
| 769 } |
732 | 770 |
733 std::string encrypted_token( | 771 std::string ParallelAuthenticator::DecryptLegacyToken( |
734 reinterpret_cast<char*>(encrypted_token_bytes.data()), | 772 const std::string& encrypted_token_hex) { |
735 encrypted_token_bytes.size()); | |
736 scoped_ptr<crypto::SymmetricKey> key( | 773 scoped_ptr<crypto::SymmetricKey> key( |
737 crypto::SymmetricKey::DeriveKeyFromPassword( | 774 crypto::SymmetricKey::DeriveKeyFromPassword( |
738 crypto::SymmetricKey::AES, UserSupplementalKeyAsAscii(), | 775 crypto::SymmetricKey::AES, UserSupplementalKeyAsAscii(), |
739 SaltAsAscii(), 1000, 256)); | 776 SaltAsAscii(), 1000, 256)); |
740 crypto::Encryptor encryptor; | 777 return DecryptTokenWithKey(key.get(), SaltAsAscii(), encrypted_token_hex); |
741 if (!encryptor.Init(key.get(), crypto::Encryptor::CTR, std::string())) | |
742 return std::string(); | |
743 | |
744 std::string nonce = SaltAsAscii().substr(0, kKeySize); | |
745 std::string token; | |
746 CHECK(encryptor.SetCounter(nonce)); | |
747 if (!encryptor.Decrypt(encrypted_token, &token)) | |
748 return std::string(); | |
749 return token; | |
750 } | 778 } |
751 | 779 |
752 | |
753 std::string ParallelAuthenticator::HashPassword(const std::string& password) { | 780 std::string ParallelAuthenticator::HashPassword(const std::string& password) { |
754 // Get salt, ascii encode, update sha with that, then update with ascii | 781 // Get salt, ascii encode, update sha with that, then update with ascii |
755 // of password, then end. | 782 // of password, then end. |
756 std::string ascii_salt = SaltAsAscii(); | 783 std::string ascii_salt = SaltAsAscii(); |
757 char passhash_buf[kPassHashLen]; | 784 char passhash_buf[kPassHashLen]; |
758 | 785 |
759 // Hash salt and password | 786 // Hash salt and password |
760 crypto::SHA256HashString(ascii_salt + password, | 787 crypto::SHA256HashString(ascii_salt + password, |
761 &passhash_buf, sizeof(passhash_buf)); | 788 &passhash_buf, sizeof(passhash_buf)); |
762 | 789 |
(...skipping 16 matching lines...) Expand all Loading... |
779 } | 806 } |
780 | 807 |
781 void ParallelAuthenticator::ResolveLoginCompletionStatus() { | 808 void ParallelAuthenticator::ResolveLoginCompletionStatus() { |
782 // Shortcut online state resolution process. | 809 // Shortcut online state resolution process. |
783 current_state_->RecordOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), | 810 current_state_->RecordOnlineLoginStatus(GaiaAuthConsumer::ClientLoginResult(), |
784 LoginFailure::None()); | 811 LoginFailure::None()); |
785 Resolve(); | 812 Resolve(); |
786 } | 813 } |
787 | 814 |
788 } // namespace chromeos | 815 } // namespace chromeos |
OLD | NEW |