X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fchrome%2Fbrowser%2Fchromeos%2Fplatform_keys%2Fplatform_keys_nss.cc;h=2265f42b5e3465b69623c406c14796a177ad68e3;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=f3a02087d69096dbc8923449d4fcb26acf01f42d;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc b/src/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc index f3a0208..2265f42 100644 --- a/src/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc +++ b/src/chrome/browser/chromeos/platform_keys/platform_keys_nss.cc @@ -72,10 +72,12 @@ class NSSOperationState { typedef base::Callback GetCertDBCallback; -// Called back with the NSSCertDatabase associated to the given |token_id|. -// Calls |callback| if the database was successfully retrieved. Used by -// GetCertDatabaseOnIOThread. -void DidGetCertDBOnIOThread(const GetCertDBCallback& callback, +// Used by GetCertDatabaseOnIOThread and called back with the requested +// NSSCertDatabase. +// If |token_id| is not empty, sets |slot_| of |state| accordingly and calls +// |callback| if the database was successfully retrieved. +void DidGetCertDBOnIOThread(const std::string& token_id, + const GetCertDBCallback& callback, NSSOperationState* state, net::NSSCertDatabase* cert_db) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); @@ -85,42 +87,50 @@ void DidGetCertDBOnIOThread(const GetCertDBCallback& callback, return; } - state->slot_ = cert_db->GetPrivateSlot(); - if (!state->slot_) { - LOG(ERROR) << "No private slot"; - state->OnError(FROM_HERE, kErrorInternal); - return; + if (!token_id.empty()) { + if (token_id == kTokenIdUser) + state->slot_ = cert_db->GetPrivateSlot(); + else if (token_id == kTokenIdSystem) + state->slot_ = cert_db->GetSystemSlot(); + + if (!state->slot_) { + LOG(ERROR) << "Slot for token id '" << token_id << "' not available."; + state->OnError(FROM_HERE, kErrorInternal); + return; + } } callback.Run(cert_db); } -// Retrieves the NSSCertDatabase from |context|. Must be called on the IO -// thread. -void GetCertDatabaseOnIOThread(content::ResourceContext* context, +// Retrieves the NSSCertDatabase from |context| and, if |token_id| is not empty, +// the slot for |token_id|. +// Must be called on the IO thread. +void GetCertDatabaseOnIOThread(const std::string& token_id, const GetCertDBCallback& callback, + content::ResourceContext* context, NSSOperationState* state) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); net::NSSCertDatabase* cert_db = GetNSSCertDatabaseForResourceContext( - context, base::Bind(&DidGetCertDBOnIOThread, callback, state)); + context, base::Bind(&DidGetCertDBOnIOThread, token_id, callback, state)); if (cert_db) - DidGetCertDBOnIOThread(callback, state, cert_db); + DidGetCertDBOnIOThread(token_id, callback, state, cert_db); } -// Asynchronously fetches the NSSCertDatabase and PK11Slot for |token_id|. -// Stores the slot in |state| and passes the database to |callback|. Will run -// |callback| on the IO thread. +// Asynchronously fetches the NSSCertDatabase for |browser_context| and, if +// |token_id| is not empty, the slot for |token_id|. Stores the slot in |state| +// and passes the database to |callback|. Will run |callback| on the IO thread. void GetCertDatabase(const std::string& token_id, const GetCertDBCallback& callback, BrowserContext* browser_context, NSSOperationState* state) { - // TODO(pneubeck): Decide which DB to retrieve depending on |token_id|. BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(&GetCertDatabaseOnIOThread, - browser_context->GetResourceContext(), + token_id, callback, + browser_context->GetResourceContext(), state)); } @@ -145,7 +155,7 @@ class GenerateRSAKeyState : public NSSOperationState { const unsigned int modulus_length_bits_; private: - // Must be called on origin thread, use CallBack() therefore. + // Must be called on origin thread, therefore use CallBack(). subtle::GenerateKeyCallback callback_; }; @@ -174,7 +184,7 @@ class SignState : public NSSOperationState { const std::string data_; private: - // Must be called on origin thread, use CallBack() therefore. + // Must be called on origin thread, therefore use CallBack(). subtle::SignCallback callback_; }; @@ -200,7 +210,7 @@ class GetCertificatesState : public NSSOperationState { scoped_ptr certs_; private: - // Must be called on origin thread, use CallBack() therefore. + // Must be called on origin thread, therefore use CallBack(). GetCertificatesCallback callback_; }; @@ -223,7 +233,7 @@ class ImportCertificateState : public NSSOperationState { scoped_refptr certificate_; private: - // Must be called on origin thread, use CallBack() therefore. + // Must be called on origin thread, therefore use CallBack(). ImportCertificateCallback callback_; }; @@ -246,10 +256,34 @@ class RemoveCertificateState : public NSSOperationState { scoped_refptr certificate_; private: - // Must be called on origin thread, use CallBack() therefore. + // Must be called on origin thread, therefore use CallBack(). RemoveCertificateCallback callback_; }; +class GetTokensState : public NSSOperationState { + public: + explicit GetTokensState(const GetTokensCallback& callback); + virtual ~GetTokensState() {} + + virtual void OnError(const tracked_objects::Location& from, + const std::string& error_message) OVERRIDE { + CallBack(from, + scoped_ptr >() /* no token ids */, + error_message); + } + + void CallBack(const tracked_objects::Location& from, + scoped_ptr > token_ids, + const std::string& error_message) { + origin_task_runner_->PostTask( + from, base::Bind(callback_, base::Passed(&token_ids), error_message)); + } + + private: + // Must be called on origin thread, therefore use CallBack(). + GetTokensCallback callback_; +}; + NSSOperationState::NSSOperationState() : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { } @@ -287,6 +321,10 @@ RemoveCertificateState::RemoveCertificateState( : certificate_(certificate), callback_(callback) { } +GetTokensState::GetTokensState(const GetTokensCallback& callback) + : callback_(callback) { +} + // Does the actual key generation on a worker thread. Used by // GenerateRSAKeyWithDB(). void GenerateRSAKeyOnWorkerThread(scoped_ptr state) { @@ -447,6 +485,14 @@ void ImportCertificateWithDB(scoped_ptr state, return; } + // Check that the private key is in the correct slot. + PK11SlotInfo* slot = + PK11_KeyForCertExists(state->certificate_->os_cert_handle(), NULL, NULL); + if (slot != state->slot_) { + state->OnError(FROM_HERE, kErrorKeyNotFound); + return; + } + const net::Error import_status = static_cast(db->AddUserCert(state->certificate_.get())); if (import_status != net::OK) { @@ -490,6 +536,20 @@ void RemoveCertificateWithDB(scoped_ptr state, &DidRemoveCertificate, base::Passed(&state), certificate_found)); } +// Does the actual work to determine which tokens are available. +void GetTokensWithDB(scoped_ptr state, + net::NSSCertDatabase* cert_db) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + scoped_ptr > token_ids(new std::vector); + + // The user's token is always available. + token_ids->push_back(kTokenIdUser); + if (cert_db->GetSystemSlot()) + token_ids->push_back(kTokenIdSystem); + + state->CallBack(FROM_HERE, token_ids.Pass(), std::string() /* no error */); +} + } // namespace namespace subtle { @@ -588,6 +648,18 @@ void RemoveCertificate(const std::string& token_id, state_ptr); } +void GetTokens(const GetTokensCallback& callback, + content::BrowserContext* browser_context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + scoped_ptr state(new GetTokensState(callback)); + // Get the pointer to |state| before base::Passed releases |state|. + NSSOperationState* state_ptr = state.get(); + GetCertDatabase(std::string() /* don't get any specific slot */, + base::Bind(&GetTokensWithDB, base::Passed(&state)), + browser_context, + state_ptr); +} + } // namespace platform_keys } // namespace chromeos