OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/platform_keys/platform_keys.h" | 5 #include "chrome/browser/chromeos/platform_keys/platform_keys.h" |
6 | 6 |
7 #include <cert.h> | |
7 #include <cryptohi.h> | 8 #include <cryptohi.h> |
9 #include <keyhi.h> | |
10 #include <secder.h> | |
8 | 11 |
9 #include "base/bind.h" | 12 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
11 #include "base/callback.h" | 14 #include "base/callback.h" |
12 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
13 #include "base/location.h" | 16 #include "base/location.h" |
14 #include "base/logging.h" | 17 #include "base/logging.h" |
15 #include "base/macros.h" | 18 #include "base/macros.h" |
16 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
20 #include "base/stl_util.h" | |
17 #include "base/thread_task_runner_handle.h" | 21 #include "base/thread_task_runner_handle.h" |
18 #include "base/threading/worker_pool.h" | 22 #include "base/threading/worker_pool.h" |
19 #include "chrome/browser/browser_process.h" | 23 #include "chrome/browser/browser_process.h" |
20 #include "chrome/browser/browser_process_platform_part_chromeos.h" | 24 #include "chrome/browser/browser_process_platform_part_chromeos.h" |
21 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" | 25 #include "chrome/browser/chromeos/net/client_cert_filter_chromeos.h" |
22 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" | 26 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" |
23 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 27 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
24 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat form_keys_api.h" | 28 #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_plat form_keys_api.h" |
25 #include "chrome/browser/net/nss_context.h" | 29 #include "chrome/browser/net/nss_context.h" |
26 #include "chrome/browser/profiles/profile.h" | 30 #include "chrome/browser/profiles/profile.h" |
27 #include "components/policy/core/common/cloud/cloud_policy_constants.h" | 31 #include "components/policy/core/common/cloud/cloud_policy_constants.h" |
28 #include "content/public/browser/browser_context.h" | 32 #include "content/public/browser/browser_context.h" |
29 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
30 #include "crypto/rsa_private_key.h" | 34 #include "crypto/rsa_private_key.h" |
31 #include "net/base/crypto_module.h" | 35 #include "net/base/crypto_module.h" |
32 #include "net/base/net_errors.h" | 36 #include "net/base/net_errors.h" |
33 #include "net/cert/cert_database.h" | 37 #include "net/cert/cert_database.h" |
34 #include "net/cert/nss_cert_database.h" | 38 #include "net/cert/nss_cert_database.h" |
35 #include "net/cert/x509_certificate.h" | 39 #include "net/cert/x509_certificate.h" |
40 #include "net/cert/x509_util_nss.h" | |
36 #include "net/ssl/client_cert_store_chromeos.h" | 41 #include "net/ssl/client_cert_store_chromeos.h" |
37 #include "net/ssl/ssl_cert_request_info.h" | 42 #include "net/ssl/ssl_cert_request_info.h" |
38 | 43 |
39 using content::BrowserContext; | 44 using content::BrowserContext; |
40 using content::BrowserThread; | 45 using content::BrowserThread; |
41 | 46 |
42 namespace { | 47 namespace { |
43 const char kErrorInternal[] = "Internal Error."; | 48 const char kErrorInternal[] = "Internal Error."; |
44 const char kErrorKeyNotFound[] = "Key not found."; | 49 const char kErrorKeyNotFound[] = "Key not found."; |
45 const char kErrorCertificateNotFound[] = "Certificate could not be found."; | 50 const char kErrorCertificateNotFound[] = "Certificate could not be found."; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
161 from, base::Bind(callback_, public_key_spki_der, error_message)); | 166 from, base::Bind(callback_, public_key_spki_der, error_message)); |
162 } | 167 } |
163 | 168 |
164 const unsigned int modulus_length_bits_; | 169 const unsigned int modulus_length_bits_; |
165 | 170 |
166 private: | 171 private: |
167 // Must be called on origin thread, therefore use CallBack(). | 172 // Must be called on origin thread, therefore use CallBack(). |
168 subtle::GenerateKeyCallback callback_; | 173 subtle::GenerateKeyCallback callback_; |
169 }; | 174 }; |
170 | 175 |
171 class SignState : public NSSOperationState { | 176 class SignRSAState : public NSSOperationState { |
172 public: | 177 public: |
173 SignState(const std::string& public_key, | 178 SignRSAState(const std::string& data, |
174 HashAlgorithm hash_algorithm, | 179 const std::string& public_key, |
175 const std::string& data, | 180 bool sign_direct_pkcs_padded, |
176 const subtle::SignCallback& callback); | 181 HashAlgorithm hash_algorithm, |
177 ~SignState() override {} | 182 const subtle::SignCallback& callback); |
183 ~SignRSAState() override {} | |
178 | 184 |
179 void OnError(const tracked_objects::Location& from, | 185 void OnError(const tracked_objects::Location& from, |
180 const std::string& error_message) override { | 186 const std::string& error_message) override { |
181 CallBack(from, std::string() /* no signature */, error_message); | 187 CallBack(from, std::string() /* no signature */, error_message); |
182 } | 188 } |
183 | 189 |
184 void CallBack(const tracked_objects::Location& from, | 190 void CallBack(const tracked_objects::Location& from, |
185 const std::string& signature, | 191 const std::string& signature, |
186 const std::string& error_message) { | 192 const std::string& error_message) { |
187 origin_task_runner_->PostTask( | 193 origin_task_runner_->PostTask( |
188 from, base::Bind(callback_, signature, error_message)); | 194 from, base::Bind(callback_, signature, error_message)); |
189 } | 195 } |
190 | 196 |
197 // The data that will be signed. | |
198 const std::string data_; | |
199 | |
200 // Must be the DER encoding of a SubjectPublicKeyInfo. | |
191 const std::string public_key_; | 201 const std::string public_key_; |
192 HashAlgorithm hash_algorithm_; | 202 |
193 const std::string data_; | 203 // If true, |data_| will not be hashed before signing. Only PKCS#1 v1.5 |
204 // padding will be applied before signing. | |
205 // If false, |hash_algorithm_| must be set to a value != NONE. | |
206 const bool sign_direct_pkcs_padded_; | |
207 | |
208 // Determines the hash algorithm that is used to digest |data| before signing. | |
209 // Ignored if |sign_direct_pkcs_padded_| is true. | |
210 const HashAlgorithm hash_algorithm_; | |
194 | 211 |
195 private: | 212 private: |
196 // Must be called on origin thread, therefore use CallBack(). | 213 // Must be called on origin thread, therefore use CallBack(). |
197 subtle::SignCallback callback_; | 214 subtle::SignCallback callback_; |
198 }; | 215 }; |
199 | 216 |
200 class SelectCertificatesState : public NSSOperationState { | 217 class SelectCertificatesState : public NSSOperationState { |
201 public: | 218 public: |
202 explicit SelectCertificatesState( | 219 explicit SelectCertificatesState( |
203 const std::string& username_hash, | 220 const std::string& username_hash, |
204 const bool use_system_key_slot, | 221 const bool use_system_key_slot, |
205 scoped_refptr<net::SSLCertRequestInfo> request, | 222 const scoped_refptr<net::SSLCertRequestInfo>& request, |
206 const subtle::SelectCertificatesCallback& callback); | 223 const subtle::SelectCertificatesCallback& callback); |
207 ~SelectCertificatesState() override {} | 224 ~SelectCertificatesState() override {} |
208 | 225 |
209 void OnError(const tracked_objects::Location& from, | 226 void OnError(const tracked_objects::Location& from, |
210 const std::string& error_message) override { | 227 const std::string& error_message) override { |
211 CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */, | 228 CallBack(from, scoped_ptr<net::CertificateList>() /* no matches */, |
212 error_message); | 229 error_message); |
213 } | 230 } |
214 | 231 |
215 void CallBack(const tracked_objects::Location& from, | 232 void CallBack(const tracked_objects::Location& from, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
251 | 268 |
252 scoped_ptr<net::CertificateList> certs_; | 269 scoped_ptr<net::CertificateList> certs_; |
253 | 270 |
254 private: | 271 private: |
255 // Must be called on origin thread, therefore use CallBack(). | 272 // Must be called on origin thread, therefore use CallBack(). |
256 GetCertificatesCallback callback_; | 273 GetCertificatesCallback callback_; |
257 }; | 274 }; |
258 | 275 |
259 class ImportCertificateState : public NSSOperationState { | 276 class ImportCertificateState : public NSSOperationState { |
260 public: | 277 public: |
261 ImportCertificateState(scoped_refptr<net::X509Certificate> certificate, | 278 ImportCertificateState(const scoped_refptr<net::X509Certificate>& certificate, |
262 const ImportCertificateCallback& callback); | 279 const ImportCertificateCallback& callback); |
263 ~ImportCertificateState() override {} | 280 ~ImportCertificateState() override {} |
264 | 281 |
265 void OnError(const tracked_objects::Location& from, | 282 void OnError(const tracked_objects::Location& from, |
266 const std::string& error_message) override { | 283 const std::string& error_message) override { |
267 CallBack(from, error_message); | 284 CallBack(from, error_message); |
268 } | 285 } |
269 | 286 |
270 void CallBack(const tracked_objects::Location& from, | 287 void CallBack(const tracked_objects::Location& from, |
271 const std::string& error_message) { | 288 const std::string& error_message) { |
272 origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); | 289 origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); |
273 } | 290 } |
274 | 291 |
275 scoped_refptr<net::X509Certificate> certificate_; | 292 scoped_refptr<net::X509Certificate> certificate_; |
276 | 293 |
277 private: | 294 private: |
278 // Must be called on origin thread, therefore use CallBack(). | 295 // Must be called on origin thread, therefore use CallBack(). |
279 ImportCertificateCallback callback_; | 296 ImportCertificateCallback callback_; |
280 }; | 297 }; |
281 | 298 |
282 class RemoveCertificateState : public NSSOperationState { | 299 class RemoveCertificateState : public NSSOperationState { |
283 public: | 300 public: |
284 RemoveCertificateState(scoped_refptr<net::X509Certificate> certificate, | 301 RemoveCertificateState(const scoped_refptr<net::X509Certificate>& certificate, |
285 const RemoveCertificateCallback& callback); | 302 const RemoveCertificateCallback& callback); |
286 ~RemoveCertificateState() override {} | 303 ~RemoveCertificateState() override {} |
287 | 304 |
288 void OnError(const tracked_objects::Location& from, | 305 void OnError(const tracked_objects::Location& from, |
289 const std::string& error_message) override { | 306 const std::string& error_message) override { |
290 CallBack(from, error_message); | 307 CallBack(from, error_message); |
291 } | 308 } |
292 | 309 |
293 void CallBack(const tracked_objects::Location& from, | 310 void CallBack(const tracked_objects::Location& from, |
294 const std::string& error_message) { | 311 const std::string& error_message) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 NSSOperationState::NSSOperationState() | 346 NSSOperationState::NSSOperationState() |
330 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { | 347 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
331 } | 348 } |
332 | 349 |
333 GenerateRSAKeyState::GenerateRSAKeyState( | 350 GenerateRSAKeyState::GenerateRSAKeyState( |
334 unsigned int modulus_length_bits, | 351 unsigned int modulus_length_bits, |
335 const subtle::GenerateKeyCallback& callback) | 352 const subtle::GenerateKeyCallback& callback) |
336 : modulus_length_bits_(modulus_length_bits), callback_(callback) { | 353 : modulus_length_bits_(modulus_length_bits), callback_(callback) { |
337 } | 354 } |
338 | 355 |
339 SignState::SignState(const std::string& public_key, | 356 SignRSAState::SignRSAState(const std::string& data, |
340 HashAlgorithm hash_algorithm, | 357 const std::string& public_key, |
341 const std::string& data, | 358 bool sign_direct_pkcs_padded, |
342 const subtle::SignCallback& callback) | 359 HashAlgorithm hash_algorithm, |
343 : public_key_(public_key), | 360 const subtle::SignCallback& callback) |
361 : data_(data), | |
362 public_key_(public_key), | |
363 sign_direct_pkcs_padded_(sign_direct_pkcs_padded), | |
344 hash_algorithm_(hash_algorithm), | 364 hash_algorithm_(hash_algorithm), |
345 data_(data), | |
346 callback_(callback) { | 365 callback_(callback) { |
347 } | 366 } |
348 | 367 |
349 SelectCertificatesState::SelectCertificatesState( | 368 SelectCertificatesState::SelectCertificatesState( |
350 const std::string& username_hash, | 369 const std::string& username_hash, |
351 const bool use_system_key_slot, | 370 const bool use_system_key_slot, |
352 scoped_refptr<net::SSLCertRequestInfo> cert_request_info, | 371 const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, |
353 const subtle::SelectCertificatesCallback& callback) | 372 const subtle::SelectCertificatesCallback& callback) |
354 : username_hash_(username_hash), | 373 : username_hash_(username_hash), |
355 use_system_key_slot_(use_system_key_slot), | 374 use_system_key_slot_(use_system_key_slot), |
356 cert_request_info_(cert_request_info), | 375 cert_request_info_(cert_request_info), |
357 callback_(callback) { | 376 callback_(callback) { |
358 } | 377 } |
359 | 378 |
360 GetCertificatesState::GetCertificatesState( | 379 GetCertificatesState::GetCertificatesState( |
361 const GetCertificatesCallback& callback) | 380 const GetCertificatesCallback& callback) |
362 : callback_(callback) { | 381 : callback_(callback) { |
363 } | 382 } |
364 | 383 |
365 ImportCertificateState::ImportCertificateState( | 384 ImportCertificateState::ImportCertificateState( |
366 scoped_refptr<net::X509Certificate> certificate, | 385 const scoped_refptr<net::X509Certificate>& certificate, |
367 const ImportCertificateCallback& callback) | 386 const ImportCertificateCallback& callback) |
368 : certificate_(certificate), callback_(callback) { | 387 : certificate_(certificate), callback_(callback) { |
369 } | 388 } |
370 | 389 |
371 RemoveCertificateState::RemoveCertificateState( | 390 RemoveCertificateState::RemoveCertificateState( |
372 scoped_refptr<net::X509Certificate> certificate, | 391 const scoped_refptr<net::X509Certificate>& certificate, |
373 const RemoveCertificateCallback& callback) | 392 const RemoveCertificateCallback& callback) |
374 : certificate_(certificate), callback_(callback) { | 393 : certificate_(certificate), callback_(callback) { |
375 } | 394 } |
376 | 395 |
377 GetTokensState::GetTokensState(const GetTokensCallback& callback) | 396 GetTokensState::GetTokensState(const GetTokensCallback& callback) |
378 : callback_(callback) { | 397 : callback_(callback) { |
379 } | 398 } |
380 | 399 |
381 // Does the actual key generation on a worker thread. Used by | 400 // Does the actual key generation on a worker thread. Used by |
382 // GenerateRSAKeyWithDB(). | 401 // GenerateRSAKeyWithDB(). |
(...skipping 25 matching lines...) Expand all Loading... | |
408 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, | 427 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, |
409 net::NSSCertDatabase* cert_db) { | 428 net::NSSCertDatabase* cert_db) { |
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
411 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. | 430 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. |
412 base::WorkerPool::PostTask( | 431 base::WorkerPool::PostTask( |
413 FROM_HERE, | 432 FROM_HERE, |
414 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), | 433 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), |
415 true /*task is slow*/); | 434 true /*task is slow*/); |
416 } | 435 } |
417 | 436 |
418 // Does the actual signing on a worker thread. Used by RSASignWithDB(). | 437 // Does the actual signing on a worker thread. Used by SignRSAWithDB(). |
419 void RSASignOnWorkerThread(scoped_ptr<SignState> state) { | 438 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) { |
420 const uint8* public_key_uint8 = | 439 const uint8* public_key_uint8 = |
421 reinterpret_cast<const uint8*>(state->public_key_.data()); | 440 reinterpret_cast<const uint8*>(state->public_key_.data()); |
422 std::vector<uint8> public_key_vector( | 441 std::vector<uint8> public_key_vector( |
423 public_key_uint8, public_key_uint8 + state->public_key_.size()); | 442 public_key_uint8, public_key_uint8 + state->public_key_.size()); |
424 | 443 |
425 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. | 444 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. |
426 scoped_ptr<crypto::RSAPrivateKey> rsa_key( | 445 scoped_ptr<crypto::RSAPrivateKey> rsa_key( |
427 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); | 446 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); |
428 if (!rsa_key || rsa_key->key()->pkcs11Slot != state->slot_) { | 447 |
448 // Fail if the key was not found. If a specific slot was requested, also fail | |
449 // if the key was found in the wrong slot. | |
450 if (!rsa_key || | |
451 (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) { | |
429 state->OnError(FROM_HERE, kErrorKeyNotFound); | 452 state->OnError(FROM_HERE, kErrorKeyNotFound); |
430 return; | 453 return; |
431 } | 454 } |
432 | 455 |
433 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; | 456 std::string signature_str; |
434 switch (state->hash_algorithm_) { | 457 if (state->sign_direct_pkcs_padded_) { |
435 case HASH_ALGORITHM_SHA1: | 458 static_assert( |
436 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; | 459 sizeof(*state->data_.data()) == sizeof(char), |
437 break; | 460 "Can't reinterpret data if it's characters are not 8 bit large."); |
Ryan Sleevi
2015/02/13 03:24:28
C++03, Section 5.3.3, p1
sizeof(char), sizeof(sig
pneubeck (no reviews)
2015/02/13 05:52:20
This check was meant to trigger in case someone ch
| |
438 case HASH_ALGORITHM_SHA256: | 461 SECItem input = {siBuffer, |
439 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; | 462 reinterpret_cast<unsigned char*>( |
440 break; | 463 const_cast<char*>(state->data_.data())), |
441 case HASH_ALGORITHM_SHA384: | 464 state->data_.size()}; |
442 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; | 465 |
443 break; | 466 // Compute signature of hash. |
444 case HASH_ALGORITHM_SHA512: | 467 int signature_len = PK11_SignatureLen(rsa_key->key()); |
445 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; | 468 if (signature_len <= 0) { |
446 break; | 469 state->OnError(FROM_HERE, kErrorInternal); |
470 return; | |
471 } | |
472 | |
473 std::vector<unsigned char> signature(signature_len); | |
474 SECItem signature_output = { | |
475 siBuffer, vector_as_array(&signature), signature.size()}; | |
476 if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess) | |
477 signature_str.assign(signature.begin(), signature.end()); | |
478 } else { | |
479 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; | |
480 switch (state->hash_algorithm_) { | |
481 case HASH_ALGORITHM_SHA1: | |
482 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; | |
483 break; | |
484 case HASH_ALGORITHM_SHA256: | |
485 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; | |
486 break; | |
487 case HASH_ALGORITHM_SHA384: | |
488 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; | |
489 break; | |
490 case HASH_ALGORITHM_SHA512: | |
491 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; | |
492 break; | |
493 case HASH_ALGORITHM_NONE: | |
494 NOTREACHED(); | |
495 break; | |
496 } | |
497 | |
498 SECItem sign_result = {siBuffer, nullptr, 0}; | |
499 if (SEC_SignData( | |
500 &sign_result, | |
501 reinterpret_cast<const unsigned char*>(state->data_.data()), | |
502 state->data_.size(), rsa_key->key(), sign_alg_tag) == SECSuccess) { | |
503 signature_str.assign(sign_result.data, | |
504 sign_result.data + sign_result.len); | |
505 } | |
447 } | 506 } |
448 | 507 |
449 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0)); | 508 if (signature_str.empty()) { |
450 if (SEC_SignData(sign_result.get(), | |
451 reinterpret_cast<const unsigned char*>(state->data_.data()), | |
452 state->data_.size(), | |
453 rsa_key->key(), | |
454 sign_alg_tag) != SECSuccess) { | |
455 LOG(ERROR) << "Couldn't sign."; | 509 LOG(ERROR) << "Couldn't sign."; |
456 state->OnError(FROM_HERE, kErrorInternal); | 510 state->OnError(FROM_HERE, kErrorInternal); |
457 return; | 511 return; |
458 } | 512 } |
459 | 513 |
460 std::string signature(reinterpret_cast<const char*>(sign_result->data), | 514 state->CallBack(FROM_HERE, signature_str, std::string() /* no error */); |
461 sign_result->len); | |
462 state->CallBack(FROM_HERE, signature, std::string() /* no error */); | |
463 } | 515 } |
464 | 516 |
465 // Continues signing with the obtained NSSCertDatabase. Used by Sign(). | 517 // Continues signing with the obtained NSSCertDatabase. Used by Sign(). |
466 void RSASignWithDB(scoped_ptr<SignState> state, net::NSSCertDatabase* cert_db) { | 518 void SignRSAWithDB(scoped_ptr<SignRSAState> state, |
519 net::NSSCertDatabase* cert_db) { | |
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
468 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. | 521 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. |
469 base::WorkerPool::PostTask( | 522 base::WorkerPool::PostTask( |
470 FROM_HERE, | 523 FROM_HERE, base::Bind(&SignRSAOnWorkerThread, base::Passed(&state)), |
471 base::Bind(&RSASignOnWorkerThread, base::Passed(&state)), | |
472 true /*task is slow*/); | 524 true /*task is slow*/); |
473 } | 525 } |
474 | 526 |
475 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list | 527 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list |
476 // of net::CertificateList and calls back. Used by | 528 // of net::CertificateList and calls back. Used by |
477 // SelectCertificatesOnIOThread(). | 529 // SelectCertificatesOnIOThread(). |
478 void DidSelectCertificatesOnIOThread( | 530 void DidSelectCertificatesOnIOThread( |
479 scoped_ptr<SelectCertificatesState> state) { | 531 scoped_ptr<SelectCertificatesState> state) { |
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 532 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
481 state->CallBack(FROM_HERE, state->certs_.Pass(), | 533 state->CallBack(FROM_HERE, state->certs_.Pass(), |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
648 } | 700 } |
649 | 701 |
650 // Get the pointer to |state| before base::Passed releases |state|. | 702 // Get the pointer to |state| before base::Passed releases |state|. |
651 NSSOperationState* state_ptr = state.get(); | 703 NSSOperationState* state_ptr = state.get(); |
652 GetCertDatabase(token_id, | 704 GetCertDatabase(token_id, |
653 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), | 705 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), |
654 browser_context, | 706 browser_context, |
655 state_ptr); | 707 state_ptr); |
656 } | 708 } |
657 | 709 |
658 void Sign(const std::string& token_id, | 710 void SignRSAPKCS1Digest(const std::string& token_id, |
659 const std::string& public_key, | 711 const std::string& data, |
660 HashAlgorithm hash_algorithm, | 712 const std::string& public_key, |
661 const std::string& data, | 713 HashAlgorithm hash_algorithm, |
662 const SignCallback& callback, | 714 const SignCallback& callback, |
663 BrowserContext* browser_context) { | 715 content::BrowserContext* browser_context) { |
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 716 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
665 scoped_ptr<SignState> state( | 717 scoped_ptr<SignRSAState> state( |
666 new SignState(public_key, hash_algorithm, data, callback)); | 718 new SignRSAState(data, public_key, false /* digest before signing */, |
719 hash_algorithm, callback)); | |
667 // Get the pointer to |state| before base::Passed releases |state|. | 720 // Get the pointer to |state| before base::Passed releases |state|. |
668 NSSOperationState* state_ptr = state.get(); | 721 NSSOperationState* state_ptr = state.get(); |
669 | 722 |
670 // The NSSCertDatabase object is not required. But in case it's not available | 723 // The NSSCertDatabase object is not required. But in case it's not available |
671 // we would get more informative error messages and we can double check that | 724 // we would get more informative error messages and we can double check that |
672 // we use a key of the correct token. | 725 // we use a key of the correct token. |
673 GetCertDatabase(token_id, | 726 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)), |
674 base::Bind(&RSASignWithDB, base::Passed(&state)), | 727 browser_context, state_ptr); |
675 browser_context, | 728 } |
676 state_ptr); | 729 |
730 void SignRSAPKCS1Raw(const std::string& token_id, | |
731 const std::string& data, | |
732 const std::string& public_key, | |
733 const SignCallback& callback, | |
734 content::BrowserContext* browser_context) { | |
735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
736 scoped_ptr<SignRSAState> state(new SignRSAState( | |
737 data, public_key, true /* sign directly without hashing */, | |
738 HASH_ALGORITHM_NONE, callback)); | |
739 // Get the pointer to |state| before base::Passed releases |state|. | |
740 NSSOperationState* state_ptr = state.get(); | |
741 | |
742 // The NSSCertDatabase object is not required. But in case it's not available | |
743 // we would get more informative error messages and we can double check that | |
744 // we use a key of the correct token. | |
745 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)), | |
746 browser_context, state_ptr); | |
677 } | 747 } |
678 | 748 |
679 void SelectClientCertificates(const ClientCertificateRequest& request, | 749 void SelectClientCertificates(const ClientCertificateRequest& request, |
680 const SelectCertificatesCallback& callback, | 750 const SelectCertificatesCallback& callback, |
681 content::BrowserContext* browser_context) { | 751 content::BrowserContext* browser_context) { |
682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 752 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
683 | 753 |
684 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( | 754 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( |
685 new net::SSLCertRequestInfo); | 755 new net::SSLCertRequestInfo); |
686 cert_request_info->cert_key_types = request.certificate_key_types; | 756 cert_request_info->cert_key_types = request.certificate_key_types; |
(...skipping 12 matching lines...) Expand all Loading... | |
699 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( | 769 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( |
700 user->username_hash(), use_system_key_slot, cert_request_info, callback)); | 770 user->username_hash(), use_system_key_slot, cert_request_info, callback)); |
701 | 771 |
702 BrowserThread::PostTask( | 772 BrowserThread::PostTask( |
703 BrowserThread::IO, FROM_HERE, | 773 BrowserThread::IO, FROM_HERE, |
704 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); | 774 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); |
705 } | 775 } |
706 | 776 |
707 } // namespace subtle | 777 } // namespace subtle |
708 | 778 |
779 bool GetPublicKey(const scoped_refptr<net::X509Certificate>& certificate, | |
780 std::string* public_key_spki_der, | |
781 net::X509Certificate::PublicKeyType* key_type, | |
782 size_t* key_size_bits) { | |
783 CHECK(public_key_spki_der); | |
784 CHECK(key_type); | |
785 CHECK(key_size_bits); | |
Ryan Sleevi
2015/02/13 03:24:28
jschuh has advised me in the past to explicitly re
pneubeck (no reviews)
2015/02/14 13:25:14
Done.
| |
786 const SECItem& spki_der = certificate->os_cert_handle()->derPublicKey; | |
787 | |
788 net::X509Certificate::PublicKeyType key_type_tmp = | |
789 net::X509Certificate::kPublicKeyTypeUnknown; | |
790 size_t key_size_bits_tmp = 0; | |
791 net::X509Certificate::GetPublicKeyInfo(certificate->os_cert_handle(), | |
792 &key_size_bits_tmp, &key_type_tmp); | |
793 | |
794 if (key_type_tmp == net::X509Certificate::kPublicKeyTypeUnknown) { | |
795 LOG(WARNING) << "Could not extract public key of certificate."; | |
796 return false; | |
797 } | |
798 if (key_type_tmp != net::X509Certificate::kPublicKeyTypeRSA) { | |
799 LOG(WARNING) << "Keys of other type than RSA are not supported."; | |
800 return false; | |
801 } | |
802 | |
803 crypto::ScopedSECKEYPublicKey public_key( | |
804 CERT_ExtractPublicKey(certificate->os_cert_handle())); | |
805 if (!public_key) { | |
806 LOG(WARNING) << "Could not extract public key of certificate."; | |
807 return false; | |
808 } | |
809 long public_exponent = DER_GetInteger(&public_key->u.rsa.publicExponent); | |
810 if (public_exponent != 65537L) { | |
811 LOG(ERROR) << "Rejecting RSA public exponent that is unequal 65537."; | |
812 return false; | |
813 } | |
814 | |
815 public_key_spki_der->assign(spki_der.data, spki_der.data + spki_der.len); | |
816 *key_type = key_type_tmp; | |
817 *key_size_bits = key_size_bits_tmp; | |
818 | |
819 return true; | |
820 } | |
821 | |
709 void GetCertificates(const std::string& token_id, | 822 void GetCertificates(const std::string& token_id, |
710 const GetCertificatesCallback& callback, | 823 const GetCertificatesCallback& callback, |
711 BrowserContext* browser_context) { | 824 BrowserContext* browser_context) { |
712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 825 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
713 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); | 826 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); |
714 // Get the pointer to |state| before base::Passed releases |state|. | 827 // Get the pointer to |state| before base::Passed releases |state|. |
715 NSSOperationState* state_ptr = state.get(); | 828 NSSOperationState* state_ptr = state.get(); |
716 GetCertDatabase(token_id, | 829 GetCertDatabase(token_id, |
717 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), | 830 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), |
718 browser_context, | 831 browser_context, |
719 state_ptr); | 832 state_ptr); |
720 } | 833 } |
721 | 834 |
722 void ImportCertificate(const std::string& token_id, | 835 void ImportCertificate(const std::string& token_id, |
723 scoped_refptr<net::X509Certificate> certificate, | 836 const scoped_refptr<net::X509Certificate>& certificate, |
724 const ImportCertificateCallback& callback, | 837 const ImportCertificateCallback& callback, |
725 BrowserContext* browser_context) { | 838 BrowserContext* browser_context) { |
726 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 839 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
727 scoped_ptr<ImportCertificateState> state( | 840 scoped_ptr<ImportCertificateState> state( |
728 new ImportCertificateState(certificate, callback)); | 841 new ImportCertificateState(certificate, callback)); |
729 // Get the pointer to |state| before base::Passed releases |state|. | 842 // Get the pointer to |state| before base::Passed releases |state|. |
730 NSSOperationState* state_ptr = state.get(); | 843 NSSOperationState* state_ptr = state.get(); |
731 | 844 |
732 // The NSSCertDatabase object is not required. But in case it's not available | 845 // The NSSCertDatabase object is not required. But in case it's not available |
733 // we would get more informative error messages and we can double check that | 846 // we would get more informative error messages and we can double check that |
734 // we use a key of the correct token. | 847 // we use a key of the correct token. |
735 GetCertDatabase(token_id, | 848 GetCertDatabase(token_id, |
736 base::Bind(&ImportCertificateWithDB, base::Passed(&state)), | 849 base::Bind(&ImportCertificateWithDB, base::Passed(&state)), |
737 browser_context, | 850 browser_context, |
738 state_ptr); | 851 state_ptr); |
739 } | 852 } |
740 | 853 |
741 void RemoveCertificate(const std::string& token_id, | 854 void RemoveCertificate(const std::string& token_id, |
742 scoped_refptr<net::X509Certificate> certificate, | 855 const scoped_refptr<net::X509Certificate>& certificate, |
743 const RemoveCertificateCallback& callback, | 856 const RemoveCertificateCallback& callback, |
744 BrowserContext* browser_context) { | 857 BrowserContext* browser_context) { |
745 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 858 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
746 scoped_ptr<RemoveCertificateState> state( | 859 scoped_ptr<RemoveCertificateState> state( |
747 new RemoveCertificateState(certificate, callback)); | 860 new RemoveCertificateState(certificate, callback)); |
748 // Get the pointer to |state| before base::Passed releases |state|. | 861 // Get the pointer to |state| before base::Passed releases |state|. |
749 NSSOperationState* state_ptr = state.get(); | 862 NSSOperationState* state_ptr = state.get(); |
750 | 863 |
751 // The NSSCertDatabase object is not required. But in case it's not available | 864 // The NSSCertDatabase object is not required. But in case it's not available |
752 // we would get more informative error messages. | 865 // we would get more informative error messages. |
(...skipping 11 matching lines...) Expand all Loading... | |
764 NSSOperationState* state_ptr = state.get(); | 877 NSSOperationState* state_ptr = state.get(); |
765 GetCertDatabase(std::string() /* don't get any specific slot */, | 878 GetCertDatabase(std::string() /* don't get any specific slot */, |
766 base::Bind(&GetTokensWithDB, base::Passed(&state)), | 879 base::Bind(&GetTokensWithDB, base::Passed(&state)), |
767 browser_context, | 880 browser_context, |
768 state_ptr); | 881 state_ptr); |
769 } | 882 } |
770 | 883 |
771 } // namespace platform_keys | 884 } // namespace platform_keys |
772 | 885 |
773 } // namespace chromeos | 886 } // namespace chromeos |
OLD | NEW |