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

Side by Side Diff: chrome/browser/chromeos/platform_keys/platform_keys_nss.cc

Issue 884073002: Implement chrome.platformKeys.getKeyPair(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert_impl2
Patch Set: Bundled Sign() arguments into a struct. Renamed to SignRSA. Created 5 years, 10 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 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
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(scoped_ptr<SignRSAParams> params,
174 HashAlgorithm hash_algorithm, 179 const subtle::SignCallback& callback);
175 const std::string& data, 180 ~SignRSAState() override {}
176 const subtle::SignCallback& callback);
177 ~SignState() override {}
178 181
179 void OnError(const tracked_objects::Location& from, 182 void OnError(const tracked_objects::Location& from,
180 const std::string& error_message) override { 183 const std::string& error_message) override {
181 CallBack(from, std::string() /* no signature */, error_message); 184 CallBack(from, std::string() /* no signature */, error_message);
182 } 185 }
183 186
184 void CallBack(const tracked_objects::Location& from, 187 void CallBack(const tracked_objects::Location& from,
185 const std::string& signature, 188 const std::string& signature,
186 const std::string& error_message) { 189 const std::string& error_message) {
187 origin_task_runner_->PostTask( 190 origin_task_runner_->PostTask(
188 from, base::Bind(callback_, signature, error_message)); 191 from, base::Bind(callback_, signature, error_message));
189 } 192 }
190 193
191 const std::string public_key_; 194 scoped_ptr<SignRSAParams> params_;
192 HashAlgorithm hash_algorithm_;
193 const std::string data_;
194 195
195 private: 196 private:
196 // Must be called on origin thread, therefore use CallBack(). 197 // Must be called on origin thread, therefore use CallBack().
197 subtle::SignCallback callback_; 198 subtle::SignCallback callback_;
198 }; 199 };
199 200
200 class SelectCertificatesState : public NSSOperationState { 201 class SelectCertificatesState : public NSSOperationState {
201 public: 202 public:
202 explicit SelectCertificatesState( 203 explicit SelectCertificatesState(
203 const std::string& username_hash, 204 const std::string& username_hash,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 NSSOperationState::NSSOperationState() 330 NSSOperationState::NSSOperationState()
330 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 331 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
331 } 332 }
332 333
333 GenerateRSAKeyState::GenerateRSAKeyState( 334 GenerateRSAKeyState::GenerateRSAKeyState(
334 unsigned int modulus_length_bits, 335 unsigned int modulus_length_bits,
335 const subtle::GenerateKeyCallback& callback) 336 const subtle::GenerateKeyCallback& callback)
336 : modulus_length_bits_(modulus_length_bits), callback_(callback) { 337 : modulus_length_bits_(modulus_length_bits), callback_(callback) {
337 } 338 }
338 339
339 SignState::SignState(const std::string& public_key, 340 SignRSAState::SignRSAState(scoped_ptr<SignRSAParams> params,
340 HashAlgorithm hash_algorithm, 341 const subtle::SignCallback& callback)
341 const std::string& data, 342 : params_(params.Pass()), callback_(callback) {
342 const subtle::SignCallback& callback)
343 : public_key_(public_key),
344 hash_algorithm_(hash_algorithm),
345 data_(data),
346 callback_(callback) {
347 } 343 }
348 344
349 SelectCertificatesState::SelectCertificatesState( 345 SelectCertificatesState::SelectCertificatesState(
350 const std::string& username_hash, 346 const std::string& username_hash,
351 const bool use_system_key_slot, 347 const bool use_system_key_slot,
352 scoped_refptr<net::SSLCertRequestInfo> cert_request_info, 348 scoped_refptr<net::SSLCertRequestInfo> cert_request_info,
353 const subtle::SelectCertificatesCallback& callback) 349 const subtle::SelectCertificatesCallback& callback)
354 : username_hash_(username_hash), 350 : username_hash_(username_hash),
355 use_system_key_slot_(use_system_key_slot), 351 use_system_key_slot_(use_system_key_slot),
356 cert_request_info_(cert_request_info), 352 cert_request_info_(cert_request_info),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, 404 void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state,
409 net::NSSCertDatabase* cert_db) { 405 net::NSSCertDatabase* cert_db) {
410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 406 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
411 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 407 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|.
412 base::WorkerPool::PostTask( 408 base::WorkerPool::PostTask(
413 FROM_HERE, 409 FROM_HERE,
414 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), 410 base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)),
415 true /*task is slow*/); 411 true /*task is slow*/);
416 } 412 }
417 413
418 // Does the actual signing on a worker thread. Used by RSASignWithDB(). 414 // Does the actual signing on a worker thread. Used by SignRSAWithDB().
419 void RSASignOnWorkerThread(scoped_ptr<SignState> state) { 415 void SignRSAOnWorkerThread(scoped_ptr<SignRSAState> state) {
416 const SignRSAParams& params = *state->params_;
420 const uint8* public_key_uint8 = 417 const uint8* public_key_uint8 =
421 reinterpret_cast<const uint8*>(state->public_key_.data()); 418 reinterpret_cast<const uint8*>(params.public_key.data());
422 std::vector<uint8> public_key_vector( 419 std::vector<uint8> public_key_vector(
423 public_key_uint8, public_key_uint8 + state->public_key_.size()); 420 public_key_uint8, public_key_uint8 + params.public_key.size());
424 421
425 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. 422 // TODO(pneubeck): This searches all slots. Change to look only at |slot_|.
426 scoped_ptr<crypto::RSAPrivateKey> rsa_key( 423 scoped_ptr<crypto::RSAPrivateKey> rsa_key(
427 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); 424 crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector));
428 if (!rsa_key || rsa_key->key()->pkcs11Slot != state->slot_) { 425
426 // Fail if the key was not found. If a specific slot was requested, also fail
427 // if the key was found in the wrong slot.
428 if (!rsa_key ||
429 (state->slot_ && rsa_key->key()->pkcs11Slot != state->slot_)) {
429 state->OnError(FROM_HERE, kErrorKeyNotFound); 430 state->OnError(FROM_HERE, kErrorKeyNotFound);
430 return; 431 return;
431 } 432 }
432 433
433 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; 434 std::vector<unsigned char> data_vec(params.data.begin(), params.data.end());
434 switch (state->hash_algorithm_) { 435 std::string signature_str;
435 case HASH_ALGORITHM_SHA1: 436 if (params.sign_direct_pkcs_padded) {
436 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 437 SECItem input = {siBuffer, vector_as_array(&data_vec), data_vec.size()};
437 break; 438
438 case HASH_ALGORITHM_SHA256: 439 // Compute signature of hash.
439 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 440 int signature_len = PK11_SignatureLen(rsa_key->key());
440 break; 441 if (signature_len <= 0) {
441 case HASH_ALGORITHM_SHA384: 442 state->OnError(FROM_HERE, kErrorInternal);
442 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 443 return;
443 break; 444 }
444 case HASH_ALGORITHM_SHA512: 445
445 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 446 std::vector<unsigned char> signature(signature_len);
446 break; 447 SECItem signature_output = {
448 siBuffer, vector_as_array(&signature), signature.size()};
449 if (PK11_Sign(rsa_key->key(), &signature_output, &input) == SECSuccess)
450 signature_str.assign(signature.begin(), signature.end());
451 } else {
452 SECOidTag sign_alg_tag = SEC_OID_UNKNOWN;
453 switch (params.hash_algorithm) {
454 case HASH_ALGORITHM_SHA1:
455 sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
456 break;
457 case HASH_ALGORITHM_SHA256:
458 sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
459 break;
460 case HASH_ALGORITHM_SHA384:
461 sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
462 break;
463 case HASH_ALGORITHM_SHA512:
464 sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
465 break;
466 case HASH_ALGORITHM_NONE:
Ryan Sleevi 2015/02/07 02:09:40 Add a default? Or are we relying on the compiler t
pneubeck (no reviews) 2015/02/08 10:52:00 yes it will. 'default' prevents the completeness c
467 NOTREACHED();
468 break;
469 }
470
471 SECItem sign_result = {siBuffer, nullptr, 0};
472 if (SEC_SignData(&sign_result, vector_as_array(&data_vec), data_vec.size(),
473 rsa_key->key(), sign_alg_tag) == SECSuccess) {
474 signature_str.assign(sign_result.data,
475 sign_result.data + sign_result.len);
476 }
447 } 477 }
448 478
449 crypto::ScopedSECItem sign_result(SECITEM_AllocItem(NULL, NULL, 0)); 479 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."; 480 LOG(ERROR) << "Couldn't sign.";
456 state->OnError(FROM_HERE, kErrorInternal); 481 state->OnError(FROM_HERE, kErrorInternal);
457 return; 482 return;
458 } 483 }
459 484
460 std::string signature(reinterpret_cast<const char*>(sign_result->data), 485 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 } 486 }
464 487
465 // Continues signing with the obtained NSSCertDatabase. Used by Sign(). 488 // Continues signing with the obtained NSSCertDatabase. Used by Sign().
466 void RSASignWithDB(scoped_ptr<SignState> state, net::NSSCertDatabase* cert_db) { 489 void SignRSAWithDB(scoped_ptr<SignRSAState> state,
490 net::NSSCertDatabase* cert_db) {
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 491 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
468 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 492 // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|.
469 base::WorkerPool::PostTask( 493 base::WorkerPool::PostTask(
470 FROM_HERE, 494 FROM_HERE, base::Bind(&SignRSAOnWorkerThread, base::Passed(&state)),
471 base::Bind(&RSASignOnWorkerThread, base::Passed(&state)),
472 true /*task is slow*/); 495 true /*task is slow*/);
473 } 496 }
474 497
475 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list 498 // Called when ClientCertStoreChromeOS::GetClientCerts is done. Builds the list
476 // of net::CertificateList and calls back. Used by 499 // of net::CertificateList and calls back. Used by
477 // SelectCertificatesOnIOThread(). 500 // SelectCertificatesOnIOThread().
478 void DidSelectCertificatesOnIOThread( 501 void DidSelectCertificatesOnIOThread(
479 scoped_ptr<SelectCertificatesState> state) { 502 scoped_ptr<SelectCertificatesState> state) {
480 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 503 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
481 state->CallBack(FROM_HERE, state->certs_.Pass(), 504 state->CallBack(FROM_HERE, state->certs_.Pass(),
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 671 }
649 672
650 // Get the pointer to |state| before base::Passed releases |state|. 673 // Get the pointer to |state| before base::Passed releases |state|.
651 NSSOperationState* state_ptr = state.get(); 674 NSSOperationState* state_ptr = state.get();
652 GetCertDatabase(token_id, 675 GetCertDatabase(token_id,
653 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), 676 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)),
654 browser_context, 677 browser_context,
655 state_ptr); 678 state_ptr);
656 } 679 }
657 680
658 void Sign(const std::string& token_id, 681 void SignRSA(const std::string& token_id,
659 const std::string& public_key, 682 scoped_ptr<SignRSAParams> params,
660 HashAlgorithm hash_algorithm, 683 const SignCallback& callback,
661 const std::string& data, 684 BrowserContext* browser_context) {
662 const SignCallback& callback,
663 BrowserContext* browser_context) {
664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 685 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
665 scoped_ptr<SignState> state( 686 scoped_ptr<SignRSAState> state(new SignRSAState(params.Pass(), callback));
666 new SignState(public_key, hash_algorithm, data, callback));
667 // Get the pointer to |state| before base::Passed releases |state|. 687 // Get the pointer to |state| before base::Passed releases |state|.
668 NSSOperationState* state_ptr = state.get(); 688 NSSOperationState* state_ptr = state.get();
669 689
670 // The NSSCertDatabase object is not required. But in case it's not available 690 // 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 691 // we would get more informative error messages and we can double check that
672 // we use a key of the correct token. 692 // we use a key of the correct token.
673 GetCertDatabase(token_id, 693 GetCertDatabase(token_id, base::Bind(&SignRSAWithDB, base::Passed(&state)),
674 base::Bind(&RSASignWithDB, base::Passed(&state)), 694 browser_context, state_ptr);
675 browser_context,
676 state_ptr);
677 } 695 }
678 696
679 void SelectClientCertificates(const ClientCertificateRequest& request, 697 void SelectClientCertificates(const ClientCertificateRequest& request,
680 const SelectCertificatesCallback& callback, 698 const SelectCertificatesCallback& callback,
681 content::BrowserContext* browser_context) { 699 content::BrowserContext* browser_context) {
682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 700 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
683 701
684 scoped_refptr<net::SSLCertRequestInfo> cert_request_info( 702 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
685 new net::SSLCertRequestInfo); 703 new net::SSLCertRequestInfo);
686 cert_request_info->cert_key_types = request.certificate_key_types; 704 cert_request_info->cert_key_types = request.certificate_key_types;
(...skipping 12 matching lines...) Expand all
699 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState( 717 scoped_ptr<SelectCertificatesState> state(new SelectCertificatesState(
700 user->username_hash(), use_system_key_slot, cert_request_info, callback)); 718 user->username_hash(), use_system_key_slot, cert_request_info, callback));
701 719
702 BrowserThread::PostTask( 720 BrowserThread::PostTask(
703 BrowserThread::IO, FROM_HERE, 721 BrowserThread::IO, FROM_HERE,
704 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state))); 722 base::Bind(&SelectCertificatesOnIOThread, base::Passed(&state)));
705 } 723 }
706 724
707 } // namespace subtle 725 } // namespace subtle
708 726
727 bool GetPublicKey(scoped_refptr<net::X509Certificate> certificate,
728 SubjectPublicKeyInfo* info) {
729 const SECItem& spki_der = certificate->os_cert_handle()->derPublicKey;
730
731 *info = SubjectPublicKeyInfo();
732 info->public_key_spki_der.assign(spki_der.data, spki_der.data + spki_der.len);
733
734 net::X509Certificate::GetPublicKeyInfo(certificate->os_cert_handle(),
735 &info->key_size_bits, &info->key_type);
736
737 if (info->key_type == net::X509Certificate::kPublicKeyTypeUnknown) {
738 LOG(WARNING) << "Could not extract public key of certificate.";
739 return false;
740 }
741 if (info->key_type == net::X509Certificate::kPublicKeyTypeRSA) {
742 // TODO(pneubeck): Verify that the public exponent equals 65537.
743
744 crypto::ScopedSECKEYPublicKey public_key(
745 CERT_ExtractPublicKey(certificate->os_cert_handle()));
746 if (!public_key) {
747 LOG(WARNING) << "Could not extract public key of certificate.";
748 return false;
749 }
750 long public_exponent = DER_GetInteger(&public_key->u.rsa.publicExponent);
751 if (public_exponent != 65537L) {
752 LOG(ERROR) << "Rejecting RSA public exponent that is unequal 65537.";
753 return false;
754 }
755 }
756 return true;
757 }
758
709 void GetCertificates(const std::string& token_id, 759 void GetCertificates(const std::string& token_id,
710 const GetCertificatesCallback& callback, 760 const GetCertificatesCallback& callback,
711 BrowserContext* browser_context) { 761 BrowserContext* browser_context) {
712 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
713 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); 763 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback));
714 // Get the pointer to |state| before base::Passed releases |state|. 764 // Get the pointer to |state| before base::Passed releases |state|.
715 NSSOperationState* state_ptr = state.get(); 765 NSSOperationState* state_ptr = state.get();
716 GetCertDatabase(token_id, 766 GetCertDatabase(token_id,
717 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), 767 base::Bind(&GetCertificatesWithDB, base::Passed(&state)),
718 browser_context, 768 browser_context,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 NSSOperationState* state_ptr = state.get(); 814 NSSOperationState* state_ptr = state.get();
765 GetCertDatabase(std::string() /* don't get any specific slot */, 815 GetCertDatabase(std::string() /* don't get any specific slot */,
766 base::Bind(&GetTokensWithDB, base::Passed(&state)), 816 base::Bind(&GetTokensWithDB, base::Passed(&state)),
767 browser_context, 817 browser_context,
768 state_ptr); 818 state_ptr);
769 } 819 }
770 820
771 } // namespace platform_keys 821 } // namespace platform_keys
772 822
773 } // namespace chromeos 823 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698