Home | History | Annotate | Download | only in net
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/net/nss_context.h"
      6 
      7 #include "base/memory/weak_ptr.h"
      8 #include "base/supports_user_data.h"
      9 #include "chrome/browser/profiles/profile_io_data.h"
     10 #include "content/public/browser/browser_thread.h"
     11 #include "crypto/nss_util_internal.h"
     12 #include "net/cert/nss_cert_database_chromeos.h"
     13 
     14 namespace {
     15 
     16 void* kDatabaseManagerKey = &kDatabaseManagerKey;
     17 
     18 class NSSCertDatabaseChromeOSManager : public base::SupportsUserData::Data {
     19  public:
     20   explicit NSSCertDatabaseChromeOSManager(const std::string& username_hash)
     21       : username_hash_(username_hash), weak_ptr_factory_(this) {
     22     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     23     crypto::ScopedPK11Slot private_slot(crypto::GetPrivateSlotForChromeOSUser(
     24         username_hash,
     25         base::Bind(&NSSCertDatabaseChromeOSManager::DidGetPrivateSlot,
     26                    weak_ptr_factory_.GetWeakPtr())));
     27     if (private_slot)
     28       DidGetPrivateSlot(private_slot.Pass());
     29   }
     30 
     31   virtual ~NSSCertDatabaseChromeOSManager() {
     32     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     33   }
     34 
     35   net::NSSCertDatabase* GetNSSCertDatabase(
     36       const base::Callback<void(net::NSSCertDatabase*)>& callback) {
     37     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     38 
     39     if (nss_cert_database_)
     40       return nss_cert_database_.get();
     41 
     42     ready_callback_list_.push_back(callback);
     43     return NULL;
     44   }
     45 
     46  private:
     47   typedef std::vector<base::Callback<void(net::NSSCertDatabase*)> >
     48       ReadyCallbackList;
     49 
     50   void DidGetPrivateSlot(crypto::ScopedPK11Slot private_slot) {
     51     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     52     nss_cert_database_.reset(new net::NSSCertDatabaseChromeOS(
     53         crypto::GetPublicSlotForChromeOSUser(username_hash_),
     54         private_slot.Pass()));
     55 
     56     ReadyCallbackList callback_list;
     57     callback_list.swap(ready_callback_list_);
     58     for (ReadyCallbackList::iterator i = callback_list.begin();
     59          i != callback_list.end();
     60          ++i) {
     61       (*i).Run(nss_cert_database_.get());
     62     }
     63   }
     64 
     65   std::string username_hash_;
     66   scoped_ptr<net::NSSCertDatabaseChromeOS> nss_cert_database_;
     67   ReadyCallbackList ready_callback_list_;
     68   base::WeakPtrFactory<NSSCertDatabaseChromeOSManager> weak_ptr_factory_;
     69 
     70   DISALLOW_COPY_AND_ASSIGN(NSSCertDatabaseChromeOSManager);
     71 };
     72 
     73 std::string GetUsername(content::ResourceContext* context) {
     74   return ProfileIOData::FromResourceContext(context)->username_hash();
     75 }
     76 
     77 }  // namespace
     78 
     79 crypto::ScopedPK11Slot GetPublicNSSKeySlotForResourceContext(
     80     content::ResourceContext* context) {
     81   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     82   return crypto::GetPublicSlotForChromeOSUser(GetUsername(context));
     83 }
     84 
     85 crypto::ScopedPK11Slot GetPrivateNSSKeySlotForResourceContext(
     86     content::ResourceContext* context,
     87     const base::Callback<void(crypto::ScopedPK11Slot)>& callback) {
     88   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     89   return crypto::GetPrivateSlotForChromeOSUser(GetUsername(context), callback);
     90 }
     91 
     92 net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext(
     93     content::ResourceContext* context,
     94     const base::Callback<void(net::NSSCertDatabase*)>& callback) {
     95   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
     96   NSSCertDatabaseChromeOSManager* manager =
     97       static_cast<NSSCertDatabaseChromeOSManager*>(
     98           context->GetUserData(kDatabaseManagerKey));
     99   if (!manager) {
    100     manager = new NSSCertDatabaseChromeOSManager(GetUsername(context));
    101     context->SetUserData(kDatabaseManagerKey, manager);
    102   }
    103   return manager->GetNSSCertDatabase(callback);
    104 }
    105