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

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

Issue 12870010: Add device-level token entryption to CertLibrary. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Renamed methods per review comments. Created 7 years, 9 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
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"
(...skipping 29 matching lines...) Expand all
40 namespace { 40 namespace {
41 41
42 // Root CA certificates that are built into Chrome use this token name. 42 // Root CA certificates that are built into Chrome use this token name.
43 const char kRootCertificateTokenName[] = "Builtin Object Token"; 43 const char kRootCertificateTokenName[] = "Builtin Object Token";
44 44
45 // Delay between certificate requests while waiting for TPM/PKCS#11 init. 45 // Delay between certificate requests while waiting for TPM/PKCS#11 init.
46 const int kRequestDelayMs = 500; 46 const int kRequestDelayMs = 500;
47 47
48 const size_t kKeySize = 16; 48 const size_t kKeySize = 16;
49 49
50 // Decrypts (AES) hex encoded encrypted token given |key| and |salt|.
51 std::string DecryptTokenWithKey(
52 crypto::SymmetricKey* key,
53 const std::string& salt,
54 const std::string& encrypted_token_hex) {
55 std::vector<uint8> encrypted_token_bytes;
56 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) {
57 LOG(WARNING) << "Corrupt encrypted token found.";
58 return std::string();
59 }
60
61 std::string encrypted_token(
62 reinterpret_cast<char*>(encrypted_token_bytes.data()),
63 encrypted_token_bytes.size());
64 crypto::Encryptor encryptor;
65 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
66 LOG(WARNING) << "Failed to initialize Encryptor.";
67 return std::string();
68 }
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 LOG(WARNING) << "Failed to decrypt token.";
75 return std::string();
76 }
77 return token;
78 }
79
80 string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) { 50 string16 GetDisplayString(net::X509Certificate* cert, bool hardware_backed) {
81 std::string org; 51 std::string org;
82 if (!cert->subject().organization_names.empty()) 52 if (!cert->subject().organization_names.empty())
83 org = cert->subject().organization_names[0]; 53 org = cert->subject().organization_names[0];
84 if (org.empty()) 54 if (org.empty())
85 org = cert->subject().GetDisplayName(); 55 org = cert->subject().GetDisplayName();
86 string16 issued_by = UTF8ToUTF16( 56 string16 issued_by = UTF8ToUTF16(
87 x509_certificate_model::GetIssuerCommonName(cert->os_cert_handle(), 57 x509_certificate_model::GetIssuerCommonName(cert->os_cert_handle(),
88 org)); // alternative text 58 org)); // alternative text
89 string16 issued_to = UTF8ToUTF16( 59 string16 issued_to = UTF8ToUTF16(
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 virtual const CertList& GetServerCertificates() const OVERRIDE { 159 virtual const CertList& GetServerCertificates() const OVERRIDE {
190 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 160 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
191 return server_certs_; 161 return server_certs_;
192 } 162 }
193 163
194 virtual const CertList& GetCACertificates() const OVERRIDE { 164 virtual const CertList& GetCACertificates() const OVERRIDE {
195 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 165 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
196 return server_ca_certs_; 166 return server_ca_certs_;
197 } 167 }
198 168
199 virtual std::string EncryptToken(const std::string& token) OVERRIDE { 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 {
200 // Don't care about token encryption while debugging. 176 // Don't care about token encryption while debugging.
201 if (!base::chromeos::IsRunningOnChromeOS()) 177 if (!base::chromeos::IsRunningOnChromeOS())
202 return token; 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;
203 194
204 if (!LoadSupplementalUserKey()) { 195 if (!LoadSupplementalUserKey()) {
205 LOG(WARNING) << "Supplemental user key is not available for encrypt."; 196 LOG(WARNING) << "Supplemental user key is not available for encrypt.";
206 return std::string(); 197 return std::string();
207 } 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) {
208 crypto::Encryptor encryptor; 209 crypto::Encryptor encryptor;
209 if (!encryptor.Init(supplemental_user_key_.get(), crypto::Encryptor::CTR, 210 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) {
210 std::string())) {
211 LOG(WARNING) << "Failed to initialize Encryptor."; 211 LOG(WARNING) << "Failed to initialize Encryptor.";
212 return std::string(); 212 return std::string();
213 } 213 }
214 std::string salt =
215 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt();
216 std::string nonce = salt.substr(0, kKeySize); 214 std::string nonce = salt.substr(0, kKeySize);
217 std::string encoded_token; 215 std::string encoded_token;
218 CHECK(encryptor.SetCounter(nonce)); 216 CHECK(encryptor.SetCounter(nonce));
219 if (!encryptor.Encrypt(token, &encoded_token)) { 217 if (!encryptor.Encrypt(token, &encoded_token)) {
220 LOG(WARNING) << "Failed to encrypt token."; 218 LOG(WARNING) << "Failed to encrypt token.";
221 return std::string(); 219 return std::string();
222 } 220 }
223 221
224 return StringToLowerASCII(base::HexEncode( 222 return StringToLowerASCII(base::HexEncode(
225 reinterpret_cast<const void*>(encoded_token.data()), 223 reinterpret_cast<const void*>(encoded_token.data()),
226 encoded_token.size())); 224 encoded_token.size()));
227 } 225 }
228 226
229 virtual std::string DecryptToken( 227 virtual std::string DecryptWithSystemSalt(
230 const std::string& encrypted_token_hex) OVERRIDE { 228 const std::string& encrypted_token_hex) OVERRIDE {
231 // Don't care about token encryption while debugging. 229 // Don't care about token encryption while debugging.
232 if (!base::chromeos::IsRunningOnChromeOS()) 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())
233 return encrypted_token_hex; 247 return encrypted_token_hex;
234 248
235 if (!LoadSupplementalUserKey()) { 249 if (!LoadSupplementalUserKey()) {
236 LOG(WARNING) << "Supplemental user key is not available for decrypt."; 250 LOG(WARNING) << "Supplemental user key is not available for decrypt.";
237 return std::string(); 251 return std::string();
238 } 252 }
239 return DecryptTokenWithKey(supplemental_user_key_.get(), 253 return DecryptTokenWithKey(
254 supplemental_user_key_.get(),
240 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(), 255 CrosLibrary::Get()->GetCryptohomeLibrary()->GetSystemSalt(),
241 encrypted_token_hex); 256 encrypted_token_hex);
242 } 257 }
243 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
244 // net::CertDatabase::Observer implementation. Observer added on UI thread. 289 // net::CertDatabase::Observer implementation. Observer added on UI thread.
245 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE { 290 virtual void OnCertTrustChanged(const net::X509Certificate* cert) OVERRIDE {
246 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 291 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
247 } 292 }
248 293
249 virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE { 294 virtual void OnCertAdded(const net::X509Certificate* cert) OVERRIDE {
250 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 295 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
251 // Only load certificates if we have completed an initial request. 296 // Only load certificates if we have completed an initial request.
252 if (certificates_loaded_) { 297 if (certificates_loaded_) {
253 BrowserThread::PostTask( 298 BrowserThread::PostTask(
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 // Set 'loaded' to true for the UI, since we are not waiting on loading. 428 // Set 'loaded' to true for the UI, since we are not waiting on loading.
384 LOG(WARNING) << "Requesting supplemental use key before login."; 429 LOG(WARNING) << "Requesting supplemental use key before login.";
385 return false; 430 return false;
386 } 431 }
387 if (!supplemental_user_key_.get()) { 432 if (!supplemental_user_key_.get()) {
388 supplemental_user_key_.reset(crypto::GetSupplementalUserKey()); 433 supplemental_user_key_.reset(crypto::GetSupplementalUserKey());
389 } 434 }
390 return supplemental_user_key_.get() != NULL; 435 return supplemental_user_key_.get() != NULL;
391 } 436 }
392 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
393 // Call this to start the certificate list initialization process. 449 // Call this to start the certificate list initialization process.
394 // Must be called from the UI thread. 450 // Must be called from the UI thread.
395 void RequestCertificates() { 451 void RequestCertificates() {
396 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 452 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
397 453
398 certificates_requested_ = true; 454 certificates_requested_ = true;
399 455
400 if (!UserManager::Get()->IsUserLoggedIn()) { 456 if (!UserManager::Get()->IsUserLoggedIn()) {
401 // If we are not logged in, we cannot load any certificates. 457 // If we are not logged in, we cannot load any certificates.
402 // Set 'loaded' to true for the UI, since we are not waiting on loading. 458 // Set 'loaded' to true for the UI, since we are not waiting on loading.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 566
511 // Cached TPM token name. 567 // Cached TPM token name.
512 std::string tpm_token_name_; 568 std::string tpm_token_name_;
513 569
514 // Cached TPM user pin. 570 // Cached TPM user pin.
515 std::string tpm_user_pin_; 571 std::string tpm_user_pin_;
516 572
517 // Supplemental user key. 573 // Supplemental user key.
518 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_; 574 scoped_ptr<crypto::SymmetricKey> supplemental_user_key_;
519 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
520 // Local state. 580 // Local state.
521 bool user_logged_in_; 581 bool user_logged_in_;
522 bool certificates_requested_; 582 bool certificates_requested_;
523 bool certificates_loaded_; 583 bool certificates_loaded_;
524 // The key store for the current user has been loaded. This flag is needed to 584 // The key store for the current user has been loaded. This flag is needed to
525 // ensure that the key store will not be loaded twice in the policy recovery 585 // ensure that the key store will not be loaded twice in the policy recovery
526 // "safe-mode". 586 // "safe-mode".
527 bool key_store_loaded_; 587 bool key_store_loaded_;
528 588
529 // Certificates. 589 // Certificates.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 net::X509Certificate* cert = GetCertificateAt(index); 667 net::X509Certificate* cert = GetCertificateAt(index);
608 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); 668 net::X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
609 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle); 669 std::string id = x509_certificate_model::GetPkcs11Id(cert_handle);
610 if (id == pkcs11_id) 670 if (id == pkcs11_id)
611 return index; 671 return index;
612 } 672 }
613 return -1; // Not found. 673 return -1; // Not found.
614 } 674 }
615 675
616 } // chromeos 676 } // chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/cert_library.h ('k') | chrome/browser/chromeos/cros/mock_cert_library.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698