1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/platform_keys/platform_keys.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <cryptohi.h> 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind_helpers.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/callback.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/compiler_specific.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/location.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/logging.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/macros.h" 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/single_thread_task_runner.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/threading/worker_pool.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/net/nss_context.h" 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/browser_context.h" 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "crypto/rsa_private_key.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/crypto_module.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/base/net_errors.h" 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/cert/cert_database.h" 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/cert/nss_cert_database.h" 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/cert/x509_certificate.h" 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using content::BrowserContext; 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using content::BrowserThread; 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorInternal[] = "Internal Error."; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorKeyNotFound[] = "Key not found."; 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorCertificateNotFound[] = "Certificate could not be found."; 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorAlgorithmNotSupported[] = "Algorithm not supported."; 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The current maximal RSA modulus length that ChromeOS's TPM supports for key 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// generation. 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const unsigned int kMaxRSAModulusLengthBits = 2048; 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace chromeos { 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace platform_keys { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace { 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Base class to store state that is common to all NSS database operations and 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// to provide convenience methods to call back. 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Keeps track of the originating task runner. 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class NSSOperationState { 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState(); 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~NSSOperationState() {} 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called if an error occurred during the execution of the NSS operation 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // described by this object. 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) = 0; 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) crypto::ScopedPK11Slot slot_; 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The task runner on which the NSS operation was called. Any reply must be 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // posted to this runner. 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NSSOperationState); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)typedef base::Callback<void(net::NSSCertDatabase* cert_db)> GetCertDBCallback; 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Used by GetCertDatabaseOnIOThread and called back with the requested 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// NSSCertDatabase. 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If |token_id| is not empty, sets |slot_| of |state| accordingly and calls 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |callback| if the database was successfully retrieved. 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void DidGetCertDBOnIOThread(const std::string& token_id, 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const GetCertDBCallback& callback, 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state, 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NSSCertDatabase* cert_db) { 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!cert_db) { 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Couldn't get NSSCertDatabase."; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorInternal); 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!token_id.empty()) { 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (token_id == kTokenIdUser) 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->slot_ = cert_db->GetPrivateSlot(); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if (token_id == kTokenIdSystem) 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->slot_ = cert_db->GetSystemSlot(); 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!state->slot_) { 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Slot for token id '" << token_id << "' not available."; 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->OnError(FROM_HERE, kErrorInternal); 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(cert_db); 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Retrieves the NSSCertDatabase from |context| and, if |token_id| is not empty, 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// the slot for |token_id|. 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Must be called on the IO thread. 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GetCertDatabaseOnIOThread(const std::string& token_id, 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GetCertDBCallback& callback, 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::ResourceContext* context, 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state) { 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext( 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context, base::Bind(&DidGetCertDBOnIOThread, token_id, callback, state)); 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cert_db) 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DidGetCertDBOnIOThread(token_id, callback, state, cert_db); 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Asynchronously fetches the NSSCertDatabase for |browser_context| and, if 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// |token_id| is not empty, the slot for |token_id|. Stores the slot in |state| 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// and passes the database to |callback|. Will run |callback| on the IO thread. 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GetCertDatabase(const std::string& token_id, 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GetCertDBCallback& callback, 126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserContext* browser_context, 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state) { 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&GetCertDatabaseOnIOThread, 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) token_id, 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback, 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser_context->GetResourceContext(), 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state)); 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GenerateRSAKeyState : public NSSOperationState { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GenerateRSAKeyState(unsigned int modulus_length_bits, 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const subtle::GenerateKeyCallback& callback); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~GenerateRSAKeyState() {} 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) OVERRIDE { 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CallBack(from, std::string() /* no public key */, error_message); 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CallBack(const tracked_objects::Location& from, 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& public_key_spki_der, 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) { 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_task_runner_->PostTask( 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) from, base::Bind(callback_, public_key_spki_der, error_message)); 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const unsigned int modulus_length_bits_; 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Must be called on origin thread, therefore use CallBack(). 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) subtle::GenerateKeyCallback callback_; 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class SignState : public NSSOperationState { 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SignState(const std::string& public_key, 1656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) HashAlgorithm hash_algorithm, 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& data, 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const subtle::SignCallback& callback); 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~SignState() {} 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) OVERRIDE { 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CallBack(from, std::string() /* no signature */, error_message); 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CallBack(const tracked_objects::Location& from, 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& signature, 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) { 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_task_runner_->PostTask( 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) from, base::Bind(callback_, signature, error_message)); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string public_key_; 1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) HashAlgorithm hash_algorithm_; 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string data_; 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Must be called on origin thread, therefore use CallBack(). 188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) subtle::SignCallback callback_; 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class GetCertificatesState : public NSSOperationState { 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) explicit GetCertificatesState(const GetCertificatesCallback& callback); 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~GetCertificatesState() {} 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) OVERRIDE { 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CallBack(from, 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<net::CertificateList>() /* no certificates */, 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_message); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CallBack(const tracked_objects::Location& from, 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<net::CertificateList> certs, 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) { 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_task_runner_->PostTask( 207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) from, base::Bind(callback_, base::Passed(&certs), error_message)); 208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<net::CertificateList> certs_; 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Must be called on origin thread, therefore use CallBack(). 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetCertificatesCallback callback_; 215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ImportCertificateState : public NSSOperationState { 218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ImportCertificateState(scoped_refptr<net::X509Certificate> certificate, 220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImportCertificateCallback& callback); 221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~ImportCertificateState() {} 222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) OVERRIDE { 225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CallBack(from, error_message); 226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CallBack(const tracked_objects::Location& from, 229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) { 230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); 231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate_; 234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Must be called on origin thread, therefore use CallBack(). 237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ImportCertificateCallback callback_; 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class RemoveCertificateState : public NSSOperationState { 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RemoveCertificateState(scoped_refptr<net::X509Certificate> certificate, 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const RemoveCertificateCallback& callback); 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~RemoveCertificateState() {} 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) OVERRIDE { 248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CallBack(from, error_message); 249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void CallBack(const tracked_objects::Location& from, 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& error_message) { 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_task_runner_->PostTask(from, base::Bind(callback_, error_message)); 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate_; 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Must be called on origin thread, therefore use CallBack(). 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RemoveCertificateCallback callback_; 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class GetTokensState : public NSSOperationState { 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit GetTokensState(const GetTokensCallback& callback); 2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~GetTokensState() {} 2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void OnError(const tracked_objects::Location& from, 2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& error_message) OVERRIDE { 2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) CallBack(from, 2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<std::vector<std::string> >() /* no token ids */, 2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error_message); 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void CallBack(const tracked_objects::Location& from, 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<std::vector<std::string> > token_ids, 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& error_message) { 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) origin_task_runner_->PostTask( 2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) from, base::Bind(callback_, base::Passed(&token_ids), error_message)); 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Must be called on origin thread, therefore use CallBack(). 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetTokensCallback callback_; 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)NSSOperationState::NSSOperationState() 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { 289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)GenerateRSAKeyState::GenerateRSAKeyState( 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unsigned int modulus_length_bits, 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const subtle::GenerateKeyCallback& callback) 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : modulus_length_bits_(modulus_length_bits), callback_(callback) { 295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)SignState::SignState(const std::string& public_key, 2986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) HashAlgorithm hash_algorithm, 299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& data, 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const subtle::SignCallback& callback) 3016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) : public_key_(public_key), 3026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) hash_algorithm_(hash_algorithm), 3036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) data_(data), 3046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) callback_(callback) { 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GetCertificatesState::GetCertificatesState( 308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GetCertificatesCallback& callback) 309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : callback_(callback) { 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ImportCertificateState::ImportCertificateState( 313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate, 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImportCertificateCallback& callback) 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : certificate_(certificate), callback_(callback) { 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)RemoveCertificateState::RemoveCertificateState( 319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate, 320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const RemoveCertificateCallback& callback) 321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : certificate_(certificate), callback_(callback) { 322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GetTokensState::GetTokensState(const GetTokensCallback& callback) 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : callback_(callback) { 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Does the actual key generation on a worker thread. Used by 329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// GenerateRSAKeyWithDB(). 330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) { 331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<crypto::RSAPrivateKey> rsa_key( 332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) crypto::RSAPrivateKey::CreateSensitive(state->slot_.get(), 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) state->modulus_length_bits_)); 334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!rsa_key) { 335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Couldn't create key."; 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorInternal); 337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<uint8> public_key_spki_der; 341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!rsa_key->ExportPublicKey(&public_key_spki_der)) { 342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(pneubeck): Remove rsa_key from storage. 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Couldn't export public key."; 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorInternal); 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->CallBack( 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string(public_key_spki_der.begin(), public_key_spki_der.end()), 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string() /* no error */); 351cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Continues generating a RSA key with the obtained NSSCertDatabase. Used by 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// GenerateRSAKey(). 355cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GenerateRSAKeyWithDB(scoped_ptr<GenerateRSAKeyState> state, 356cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NSSCertDatabase* cert_db) { 357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WorkerPool::PostTask( 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&GenerateRSAKeyOnWorkerThread, base::Passed(&state)), 362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /*task is slow*/); 363cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 364cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Does the actual signing on a worker thread. Used by RSASignWithDB(). 366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RSASignOnWorkerThread(scoped_ptr<SignState> state) { 367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const uint8* public_key_uint8 = 368cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reinterpret_cast<const uint8*>(state->public_key_.data()); 369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<uint8> public_key_vector( 370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public_key_uint8, public_key_uint8 + state->public_key_.size()); 371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(pneubeck): This searches all slots. Change to look only at |slot_|. 373cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<crypto::RSAPrivateKey> rsa_key( 374cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) crypto::RSAPrivateKey::FindFromPublicKeyInfo(public_key_vector)); 375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!rsa_key || rsa_key->key()->pkcs11Slot != state->slot_) { 376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorKeyNotFound); 377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) SECOidTag sign_alg_tag = SEC_OID_UNKNOWN; 3816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) switch (state->hash_algorithm_) { 3826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) case HASH_ALGORITHM_SHA1: 3836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 3846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) break; 3856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) case HASH_ALGORITHM_SHA256: 3866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 3876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) break; 3886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) case HASH_ALGORITHM_SHA384: 3896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 3906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) break; 3916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) case HASH_ALGORITHM_SHA512: 3926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 3936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) break; 3946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 3956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SECItem sign_result = {siBuffer, NULL, 0}; 397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (SEC_SignData(&sign_result, 398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reinterpret_cast<const unsigned char*>(state->data_.data()), 399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->data_.size(), 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) rsa_key->key(), 4016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) sign_alg_tag) != SECSuccess) { 402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Couldn't sign."; 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorInternal); 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string signature(reinterpret_cast<const char*>(sign_result.data), 408cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sign_result.len); 409cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->CallBack(FROM_HERE, signature, std::string() /* no error */); 410cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 411cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 412cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Continues signing with the obtained NSSCertDatabase. Used by Sign(). 413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RSASignWithDB(scoped_ptr<SignState> state, net::NSSCertDatabase* cert_db) { 414cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Only the slot and not the NSSCertDatabase is required. Ignore |cert_db|. 416cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WorkerPool::PostTask( 417cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&RSASignOnWorkerThread, base::Passed(&state)), 419cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /*task is slow*/); 420cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Filters the obtained certificates on a worker thread. Used by 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// DidGetCertificates(). 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void FilterCertificatesOnWorkerThread(scoped_ptr<GetCertificatesState> state) { 425cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<net::CertificateList> client_certs(new net::CertificateList); 426cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (net::CertificateList::const_iterator it = state->certs_->begin(); 427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != state->certs_->end(); 428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::X509Certificate::OSCertHandle cert_handle = (*it)->os_cert_handle(); 430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) crypto::ScopedPK11Slot cert_slot(PK11_KeyForCertExists(cert_handle, 431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL, // keyPtr 432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NULL)); // wincx 433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Keep only user certificates, i.e. certs for which the private key is 435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // present and stored in the queried slot. 436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cert_slot != state->slot_) 437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continue; 438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client_certs->push_back(*it); 440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->CallBack(FROM_HERE, client_certs.Pass(), std::string() /* no error */); 443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Passes the obtained certificates to the worker thread for filtering. Used by 446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// GetCertificatesWithDB(). 447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DidGetCertificates(scoped_ptr<GetCertificatesState> state, 448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<net::CertificateList> all_certs) { 449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->certs_ = all_certs.Pass(); 451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WorkerPool::PostTask( 452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FROM_HERE, 453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&FilterCertificatesOnWorkerThread, base::Passed(&state)), 454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /*task is slow*/); 455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Continues getting certificates with the obtained NSSCertDatabase. Used by 458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// GetCertificates(). 459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GetCertificatesWithDB(scoped_ptr<GetCertificatesState> state, 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NSSCertDatabase* cert_db) { 461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer to slot before base::Passed releases |state|. 463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PK11SlotInfo* slot = state->slot_.get(); 464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cert_db->ListCertsInSlot( 465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&DidGetCertificates, base::Passed(&state)), slot); 466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Does the actual certificate importing on the IO thread. Used by 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// ImportCertificate(). 470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ImportCertificateWithDB(scoped_ptr<ImportCertificateState> state, 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NSSCertDatabase* cert_db) { 472cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 473cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(pneubeck): Use |state->slot_| to verify that we're really importing to 474cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // the correct token. 475cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |cert_db| is not required, ignore it. 476cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::CertDatabase* db = net::CertDatabase::GetInstance(); 477cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 478cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const net::Error cert_status = 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<net::Error>(db->CheckUserCert(state->certificate_.get())); 480cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cert_status == net::ERR_NO_PRIVATE_KEY_FOR_CERT) { 481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorKeyNotFound); 482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 483cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (cert_status != net::OK) { 484cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, net::ErrorToString(cert_status)); 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Check that the private key is in the correct slot. 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PK11SlotInfo* slot = 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PK11_KeyForCertExists(state->certificate_->os_cert_handle(), NULL, NULL); 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (slot != state->slot_) { 4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->OnError(FROM_HERE, kErrorKeyNotFound); 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const net::Error import_status = 497cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<net::Error>(db->AddUserCert(state->certificate_.get())); 498cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (import_status != net::OK) { 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) LOG(ERROR) << "Could not import certificate."; 500cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, net::ErrorToString(import_status)); 501cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 502cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 503cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 504cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->CallBack(FROM_HERE, std::string() /* no error */); 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called on IO thread after the certificate removal is finished. 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DidRemoveCertificate(scoped_ptr<RemoveCertificateState> state, 509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool certificate_found, 510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool success) { 511cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 512cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // CertificateNotFound error has precedence over an internal error. 513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!certificate_found) { 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorCertificateNotFound); 515cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 516cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 517cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!success) { 518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorInternal); 519cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 520cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 521cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 522cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->CallBack(FROM_HERE, std::string() /* no error */); 523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 524cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Does the actual certificate removal on the IO thread. Used by 526cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// RemoveCertificate(). 527cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RemoveCertificateWithDB(scoped_ptr<RemoveCertificateState> state, 528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) net::NSSCertDatabase* cert_db) { 529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer before base::Passed clears |state|. 531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate = state->certificate_; 532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool certificate_found = certificate->os_cert_handle()->isperm; 533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cert_db->DeleteCertAndKeyAsync( 534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) certificate, 535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind( 536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) &DidRemoveCertificate, base::Passed(&state), certificate_found)); 537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Does the actual work to determine which tokens are available. 5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GetTokensWithDB(scoped_ptr<GetTokensState> state, 5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::NSSCertDatabase* cert_db) { 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<std::vector<std::string> > token_ids(new std::vector<std::string>); 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The user's token is always available. 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) token_ids->push_back(kTokenIdUser); 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (cert_db->GetSystemSlot()) 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) token_ids->push_back(kTokenIdSystem); 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->CallBack(FROM_HERE, token_ids.Pass(), std::string() /* no error */); 5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace 554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 555f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace subtle { 556f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GenerateRSAKey(const std::string& token_id, 558f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unsigned int modulus_length_bits, 559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GenerateKeyCallback& callback, 560f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserContext* browser_context) { 561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<GenerateRSAKeyState> state( 563f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) new GenerateRSAKeyState(modulus_length_bits, callback)); 564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 565f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (modulus_length_bits > kMaxRSAModulusLengthBits) { 566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state->OnError(FROM_HERE, kErrorAlgorithmNotSupported); 567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 568cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer to |state| before base::Passed releases |state|. 571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state_ptr = state.get(); 572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetCertDatabase(token_id, 573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), 574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_context, 575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state_ptr); 576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Sign(const std::string& token_id, 579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& public_key, 5806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) HashAlgorithm hash_algorithm, 581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& data, 582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const SignCallback& callback, 583f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserContext* browser_context) { 584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<SignState> state( 5866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) new SignState(public_key, hash_algorithm, data, callback)); 587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer to |state| before base::Passed releases |state|. 588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state_ptr = state.get(); 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The NSSCertDatabase object is not required. But in case it's not available 591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // we would get more informative error messages and we can double check that 592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // we use a key of the correct token. 593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetCertDatabase(token_id, 594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&RSASignWithDB, base::Passed(&state)), 595f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_context, 596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state_ptr); 597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 599f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} // namespace subtle 600f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GetCertificates(const std::string& token_id, 602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const GetCertificatesCallback& callback, 603f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserContext* browser_context) { 604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); 606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer to |state| before base::Passed releases |state|. 607cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state_ptr = state.get(); 608cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetCertDatabase(token_id, 609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&GetCertificatesWithDB, base::Passed(&state)), 610f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_context, 611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state_ptr); 612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ImportCertificate(const std::string& token_id, 615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate, 616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const ImportCertificateCallback& callback, 617f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserContext* browser_context) { 618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<ImportCertificateState> state( 620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new ImportCertificateState(certificate, callback)); 621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer to |state| before base::Passed releases |state|. 622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state_ptr = state.get(); 623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The NSSCertDatabase object is not required. But in case it's not available 625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // we would get more informative error messages and we can double check that 626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // we use a key of the correct token. 627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetCertDatabase(token_id, 628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ImportCertificateWithDB, base::Passed(&state)), 629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_context, 630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state_ptr); 631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RemoveCertificate(const std::string& token_id, 634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<net::X509Certificate> certificate, 635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const RemoveCertificateCallback& callback, 636f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) BrowserContext* browser_context) { 637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<RemoveCertificateState> state( 639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new RemoveCertificateState(certificate, callback)); 640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get the pointer to |state| before base::Passed releases |state|. 641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NSSOperationState* state_ptr = state.get(); 642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The NSSCertDatabase object is not required. But in case it's not available 644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // we would get more informative error messages. 645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetCertDatabase(token_id, 646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&RemoveCertificateWithDB, base::Passed(&state)), 647f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) browser_context, 648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) state_ptr); 649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GetTokens(const GetTokensCallback& callback, 6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) content::BrowserContext* browser_context) { 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<GetTokensState> state(new GetTokensState(callback)); 6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Get the pointer to |state| before base::Passed releases |state|. 6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NSSOperationState* state_ptr = state.get(); 6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetCertDatabase(std::string() /* don't get any specific slot */, 6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&GetTokensWithDB, base::Passed(&state)), 6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser_context, 6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state_ptr); 6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 6625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace platform_keys 664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace chromeos 666