OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "chromeos/network/cert_loader.h" | 5 #include "chromeos/network/cert_loader.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/observer_list.h" | 10 #include "base/observer_list.h" |
11 #include "base/strings/string_number_conversions.h" | |
11 #include "base/task_runner_util.h" | 12 #include "base/task_runner_util.h" |
12 #include "base/threading/worker_pool.h" | 13 #include "base/threading/worker_pool.h" |
13 #include "chromeos/dbus/cryptohome_client.h" | 14 #include "chromeos/dbus/cryptohome_client.h" |
14 #include "chromeos/dbus/dbus_thread_manager.h" | 15 #include "chromeos/dbus/dbus_thread_manager.h" |
15 #include "crypto/encryptor.h" | 16 #include "crypto/encryptor.h" |
16 #include "crypto/nss_util.h" | 17 #include "crypto/nss_util.h" |
17 #include "crypto/sha2.h" | 18 #include "crypto/sha2.h" |
18 #include "crypto/symmetric_key.h" | 19 #include "crypto/symmetric_key.h" |
19 #include "net/cert/nss_cert_database.h" | 20 #include "net/cert/nss_cert_database.h" |
20 | 21 |
21 namespace chromeos { | 22 namespace chromeos { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
25 // Delay between certificate requests while waiting for TPM/PKCS#11 init. | 26 // Delay between certificate requests while waiting for TPM/PKCS#11 init. |
26 const int kRequestDelayMs = 500; | 27 const int kRequestDelayMs = 500; |
27 | 28 |
28 net::CertificateList* LoadNSSCertificates() { | 29 net::CertificateList* LoadNSSCertificates() { |
29 net::CertificateList* cert_list(new net::CertificateList()); | 30 net::CertificateList* cert_list(new net::CertificateList()); |
30 net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); | 31 if (base::chromeos::IsRunningOnChromeOS()) |
pneubeck (no reviews)
2013/05/13 09:29:36
did or how did certificates work in chromeos-on-li
stevenjb
2013/05/13 20:25:52
I do not believe that they ever have worked.
| |
32 net::NSSCertDatabase::GetInstance()->ListCerts(cert_list); | |
31 return cert_list; | 33 return cert_list; |
32 } | 34 } |
33 | 35 |
34 } // namespace | 36 } // namespace |
35 | 37 |
36 static CertLoader* g_cert_loader = NULL; | 38 static CertLoader* g_cert_loader = NULL; |
37 | 39 |
38 // static | 40 // static |
39 void CertLoader::Initialize() { | 41 void CertLoader::Initialize() { |
40 CHECK(!g_cert_loader); | 42 CHECK(!g_cert_loader); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 certificates_requested_ = true; | 114 certificates_requested_ = true; |
113 | 115 |
114 VLOG(1) << "Requesting Certificates."; | 116 VLOG(1) << "Requesting Certificates."; |
115 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( | 117 DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsEnabled( |
116 base::Bind(&CertLoader::OnTpmIsEnabled, | 118 base::Bind(&CertLoader::OnTpmIsEnabled, |
117 weak_ptr_factory_.GetWeakPtr())); | 119 weak_ptr_factory_.GetWeakPtr())); |
118 | 120 |
119 return; | 121 return; |
120 } | 122 } |
121 | 123 |
124 // For background see this discussion on dev-tech-crypto.lists.mozilla.org: | |
pneubeck (no reviews)
2013/05/13 09:29:36
Nit: maybe drop a comment where you copied this fr
| |
125 // http://web.archiveorange.com/archive/v/6JJW7E40sypfZGtbkzxX | |
126 // | |
127 // NOTE: This function relies on the convention that the same PKCS#11 ID | |
128 // is shared between a certificate and its associated private and public | |
129 // keys. I tried to implement this with PK11_GetLowLevelKeyIDForCert(), | |
130 // but that always returns NULL on Chrome OS for me. | |
131 std::string CertLoader::GetPkcs11IdForCert( | |
132 const net::X509Certificate& cert) const { | |
133 if (!IsHardwareBacked()) | |
134 return std::string(); | |
135 | |
136 CERTCertificateStr* cert_handle = cert.os_cert_handle(); | |
137 SECKEYPrivateKey *priv_key = | |
138 PK11_FindKeyByAnyCert(cert_handle, NULL /* wincx */); | |
139 if (!priv_key) | |
140 return std::string(); | |
141 | |
142 // Get the CKA_ID attribute for a key. | |
143 SECItem* sec_item = PK11_GetLowLevelKeyIDForPrivateKey(priv_key); | |
144 std::string pkcs11_id; | |
145 if (sec_item) { | |
146 pkcs11_id = base::HexEncode(sec_item->data, sec_item->len); | |
147 SECITEM_FreeItem(sec_item, PR_TRUE); | |
148 } | |
149 SECKEY_DestroyPrivateKey(priv_key); | |
150 | |
151 return pkcs11_id; | |
152 } | |
153 | |
122 void CertLoader::OnTpmIsEnabled(DBusMethodCallStatus call_status, | 154 void CertLoader::OnTpmIsEnabled(DBusMethodCallStatus call_status, |
123 bool tpm_is_enabled) { | 155 bool tpm_is_enabled) { |
124 VLOG(1) << "OnTpmIsEnabled: " << tpm_is_enabled; | 156 VLOG(1) << "OnTpmIsEnabled: " << tpm_is_enabled; |
125 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) { | 157 if (call_status != DBUS_METHOD_CALL_SUCCESS || !tpm_is_enabled) { |
126 // TPM is not enabled, so proceed with empty tpm token name. | 158 // TPM is not enabled, so proceed with empty tpm token name. |
127 VLOG(1) << "TPM not available."; | 159 VLOG(1) << "TPM not available."; |
128 StartLoadCertificates(); | 160 StartLoadCertificates(); |
129 } else if (tpm_token_ready_) { | 161 } else if (tpm_token_ready_) { |
130 // Once the TPM token is ready, initialize it. | 162 // Once the TPM token is ready, initialize it. |
131 InitializeTPMToken(); | 163 InitializeTPMToken(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 const char kHardcodedTpmSlot[] = "0"; | 197 const char kHardcodedTpmSlot[] = "0"; |
166 tpm_token_slot_ = kHardcodedTpmSlot; | 198 tpm_token_slot_ = kHardcodedTpmSlot; |
167 tpm_user_pin_ = user_pin; | 199 tpm_user_pin_ = user_pin; |
168 tpm_token_ready_ = true; | 200 tpm_token_ready_ = true; |
169 | 201 |
170 InitializeTPMToken(); | 202 InitializeTPMToken(); |
171 } | 203 } |
172 | 204 |
173 void CertLoader::InitializeTPMToken() { | 205 void CertLoader::InitializeTPMToken() { |
174 VLOG(1) << "InitializeTPMToken"; | 206 VLOG(1) << "InitializeTPMToken"; |
175 if (!crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { | 207 if (base::chromeos::IsRunningOnChromeOS() && |
208 !crypto::InitializeTPMToken(tpm_token_name_, tpm_user_pin_)) { | |
176 MaybeRetryRequestCertificates(); | 209 MaybeRetryRequestCertificates(); |
177 return; | 210 return; |
178 } | 211 } |
179 StartLoadCertificates(); | 212 StartLoadCertificates(); |
180 } | 213 } |
181 | 214 |
182 void CertLoader::StartLoadCertificates() { | 215 void CertLoader::StartLoadCertificates() { |
183 VLOG(1) << "Start Load Certificates"; | 216 VLOG(1) << "Start Load Certificates"; |
184 base::PostTaskAndReplyWithResult( | 217 base::PostTaskAndReplyWithResult( |
185 base::WorkerPool::GetTaskRunner(true /* task_is_slow */), | 218 base::WorkerPool::GetTaskRunner(true /* task_is_slow */), |
(...skipping 20 matching lines...) Expand all Loading... | |
206 NotifyCertificatesLoaded(true); | 239 NotifyCertificatesLoaded(true); |
207 } else { | 240 } else { |
208 NotifyCertificatesLoaded(false); | 241 NotifyCertificatesLoaded(false); |
209 } | 242 } |
210 } | 243 } |
211 | 244 |
212 void CertLoader::MaybeRetryRequestCertificates() { | 245 void CertLoader::MaybeRetryRequestCertificates() { |
213 if (!request_task_.is_null()) | 246 if (!request_task_.is_null()) |
214 return; | 247 return; |
215 | 248 |
249 LOG(WARNING) << "Re-Requesting Certificates."; | |
pneubeck (no reviews)
2013/05/13 09:29:36
nit: if this is happens frequently on normal start
stevenjb
2013/05/13 20:25:52
It doesn't, or shouldn't.
| |
250 | |
216 // Cryptohome does not notify us when the token is ready, so call | 251 // Cryptohome does not notify us when the token is ready, so call |
217 // this again after a delay. | 252 // this again after a delay. |
218 request_task_ = base::Bind(&CertLoader::RequestCertificatesTask, | 253 request_task_ = base::Bind(&CertLoader::RequestCertificatesTask, |
219 weak_ptr_factory_.GetWeakPtr()); | 254 weak_ptr_factory_.GetWeakPtr()); |
220 MessageLoop::current()->PostDelayedTask( | 255 MessageLoop::current()->PostDelayedTask( |
221 FROM_HERE, | 256 FROM_HERE, |
222 request_task_, | 257 request_task_, |
223 base::TimeDelta::FromMilliseconds(kRequestDelayMs)); | 258 base::TimeDelta::FromMilliseconds(kRequestDelayMs)); |
224 } | 259 } |
225 | 260 |
(...skipping 25 matching lines...) Expand all Loading... | |
251 StartLoadCertificates(); | 286 StartLoadCertificates(); |
252 } | 287 } |
253 | 288 |
254 void CertLoader::LoggedInStateChanged(LoginState::LoggedInState state) { | 289 void CertLoader::LoggedInStateChanged(LoginState::LoggedInState state) { |
255 VLOG(1) << "LoggedInStateChanged: " << state; | 290 VLOG(1) << "LoggedInStateChanged: " << state; |
256 if (LoginState::Get()->IsUserLoggedIn() && !certificates_requested_) | 291 if (LoginState::Get()->IsUserLoggedIn() && !certificates_requested_) |
257 RequestCertificates(); | 292 RequestCertificates(); |
258 } | 293 } |
259 | 294 |
260 } // namespace chromeos | 295 } // namespace chromeos |
OLD | NEW |