Index: chrome/browser/chromeos/cros/cert_library.cc |
diff --git a/chrome/browser/chromeos/cros/cert_library.cc b/chrome/browser/chromeos/cros/cert_library.cc |
index 985f9137351cb57162b5faabdeb7e1b36a598cd6..84ba2812f7f99a7f8b9ee923dece0ed9258fddf4 100644 |
--- a/chrome/browser/chromeos/cros/cert_library.cc |
+++ b/chrome/browser/chromeos/cros/cert_library.cc |
@@ -47,36 +47,6 @@ const int kRequestDelayMs = 500; |
const size_t kKeySize = 16; |
-// Decrypts (AES) hex encoded encrypted token given |key| and |salt|. |
-std::string DecryptTokenWithKey( |
- crypto::SymmetricKey* key, |
- const std::string& salt, |
- const std::string& encrypted_token_hex) { |
- std::vector<uint8> encrypted_token_bytes; |
- if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) { |
- LOG(WARNING) << "Corrupt encrypted token found."; |
- return std::string(); |
- } |
- |
- std::string encrypted_token( |
- reinterpret_cast<char*>(encrypted_token_bytes.data()), |
- encrypted_token_bytes.size()); |
- crypto::Encryptor encryptor; |
- if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) { |
- LOG(WARNING) << "Failed to initialize Encryptor."; |
- return std::string(); |
- } |
- |
- std::string nonce = salt.substr(0, kKeySize); |
- std::string token; |
- CHECK(encryptor.SetCounter(nonce)); |
- if (!encryptor.Decrypt(encrypted_token, &token)) { |
- LOG(WARNING) << "Failed to decrypt token."; |
- return std::string(); |
- } |
- return token; |
-} |
- |
string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) { |
std::string org; |
if (!cert->subject().organization_names.empty()) |
@@ -196,7 +166,28 @@ class CertLibraryImpl |
return server_ca_certs_; |
} |
- virtual std::string EncryptToken(const std::string& token) OVERRIDE { |
+ virtual crypto::SymmetricKey* PassphraseToKey(const std::string& passprhase, |
+ const std::string& salt) { |
+ return crypto::SymmetricKey::DeriveKeyFromPassword( |
+ crypto::SymmetricKey::AES, passprhase, salt, 1000, 256); |
+ } |
+ |
+ virtual std::string EncryptWithSystemSalt(const std::string& token) OVERRIDE { |
+ // Don't care about token encryption while debugging. |
+ if (!base::chromeos::IsRunningOnChromeOS()) |
+ return token; |
+ |
+ if (!LoadSystemSaltKey()) { |
+ LOG(WARNING) << "System salt key is not available for encrypt."; |
+ return std::string(); |
+ } |
+ return EncryptTokenWithKey( |
+ system_salt_key_.get(), |
+ CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), |
+ token); |
+ } |
+ |
+ virtual std::string EncryptWithUserKey(const std::string& token) OVERRIDE { |
// Don't care about token encryption while debugging. |
if (!base::chromeos::IsRunningOnChromeOS()) |
return token; |
@@ -205,14 +196,21 @@ class CertLibraryImpl |
LOG(WARNING) << "Supplemental user key is not available for encrypt."; |
return std::string(); |
} |
+ return EncryptTokenWithKey( |
+ supplemental_user_key_.get(), |
+ CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), |
+ token); |
+ } |
+ |
+ // Encrypts (AES) the token given |key| and |salt|. |
+ virtual std::string EncryptTokenWithKey(crypto::SymmetricKey* key, |
+ const std::string& salt, |
+ const std::string& token) { |
crypto::Encryptor encryptor; |
- if (!encryptor.Init(supplemental_user_key_.get(), crypto::Encryptor::CTR, |
- std::string())) { |
+ if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) { |
LOG(WARNING) << "Failed to initialize Encryptor."; |
return std::string(); |
} |
- std::string salt = |
- CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(); |
std::string nonce = salt.substr(0, kKeySize); |
std::string encoded_token; |
CHECK(encryptor.SetCounter(nonce)); |
@@ -226,7 +224,23 @@ class CertLibraryImpl |
encoded_token.size())); |
} |
- virtual std::string DecryptToken( |
+ virtual std::string DecryptWithSystemSalt( |
+ const std::string& encrypted_token_hex) OVERRIDE { |
+ // Don't care about token encryption while debugging. |
+ if (!base::chromeos::IsRunningOnChromeOS()) |
+ return encrypted_token_hex; |
+ |
+ if (!LoadSystemSaltKey()) { |
+ LOG(WARNING) << "System salt key is not available for decrypt."; |
+ return std::string(); |
+ } |
+ return DecryptTokenWithKey( |
+ system_salt_key_.get(), |
+ CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), |
+ encrypted_token_hex); |
+ } |
+ |
+ virtual std::string DecryptWithUserKey( |
const std::string& encrypted_token_hex) OVERRIDE { |
// Don't care about token encryption while debugging. |
if (!base::chromeos::IsRunningOnChromeOS()) |
@@ -236,11 +250,42 @@ class CertLibraryImpl |
LOG(WARNING) << "Supplemental user key is not available for decrypt."; |
return std::string(); |
} |
- return DecryptTokenWithKey(supplemental_user_key_.get(), |
+ return DecryptTokenWithKey( |
+ supplemental_user_key_.get(), |
CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), |
encrypted_token_hex); |
} |
+ // Decrypts (AES) hex encoded encrypted token given |key| and |salt|. |
+ virtual std::string DecryptTokenWithKey( |
+ crypto::SymmetricKey* key, |
+ const std::string& salt, |
+ const std::string& encrypted_token_hex) { |
+ std::vector<uint8> encrypted_token_bytes; |
+ if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) { |
+ LOG(WARNING) << "Corrupt encrypted token found."; |
+ return std::string(); |
+ } |
+ |
+ std::string encrypted_token( |
+ reinterpret_cast<char*>(encrypted_token_bytes.data()), |
+ encrypted_token_bytes.size()); |
+ crypto::Encryptor encryptor; |
+ if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) { |
+ LOG(WARNING) << "Failed to initialize Encryptor."; |
+ return std::string(); |
+ } |
+ |
+ std::string nonce = salt.substr(0, kKeySize); |
+ std::string token; |
+ CHECK(encryptor.SetCounter(nonce)); |
+ if (!encryptor.Decrypt(encrypted_token, &token)) { |
+ LOG(WARNING) << "Failed to decrypt token."; |
+ return std::string(); |
+ } |
+ return token; |
+ } |
+ |
// net::CertDatabase::Observer implementation. Observer added on UI thread. |
virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE { |
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
@@ -390,6 +435,17 @@ class CertLibraryImpl |
return supplemental_user_key_.get() != NULL; |
} |
+ // TODO: should this use the system salt for both the password and the salt |
+ // value, or should this use a separate salt value? |
+ bool LoadSystemSaltKey() { |
+ if (!system_salt_key_.get()) { |
+ system_salt_key_.reset(PassphraseToKey( |
+ CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), |
+ CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt())); |
+ } |
+ return system_salt_key_.get() != NULL; |
+ } |
+ |
// Call this to start the certificate list initialization process. |
// Must be called from the UI thread. |
void RequestCertificates() { |
@@ -517,6 +573,10 @@ class CertLibraryImpl |
// Supplemental user key. |
scoped_ptr<crypto::SymmetricKey> supplemental_user_key_; |
+ // A key based on the system salt. Useful for encrypting device-level |
+ // data for which we have no additional credentials. |
+ scoped_ptr<crypto::SymmetricKey> system_salt_key_; |
+ |
// Local state. |
bool user_logged_in_; |
bool certificates_requested_; |