Chromium Code Reviews| Index: net/cert/nss_cert_database_chromeos.cc |
| diff --git a/net/cert/nss_cert_database_chromeos.cc b/net/cert/nss_cert_database_chromeos.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d50d5b1f46cc2c6e7126315759a88f901c941f19 |
| --- /dev/null |
| +++ b/net/cert/nss_cert_database_chromeos.cc |
| @@ -0,0 +1,179 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "net/cert/nss_cert_database_chromeos.h" |
| + |
| +#include <cert.h> |
| +#include <pk11pub.h> |
| + |
| +#include <map> |
| + |
| +#include "base/bind.h" |
| +#include "base/lazy_instance.h" |
| +#include "base/stl_util.h" |
| +#include "base/threading/non_thread_safe.h" |
| +#include "crypto/nss_util.h" |
| +#include "crypto/nss_util_internal.h" |
| +#include "net/base/crypto_module.h" |
| +#include "net/cert/x509_certificate.h" |
| + |
| +namespace net { |
| + |
| +class NSSCertDatabaseChromeOS::Manager : public base::NonThreadSafe { |
| + public: |
| + ~Manager() { |
| + STLDeleteValues(&user_db_map_); |
| + } |
| + |
| + NSSCertDatabase* GetForUser( |
| + const std::string& username_hash, |
| + const base::Callback<void(NSSCertDatabase*)>& callback) { |
| + DCHECK(CalledOnValidThread()); |
| + UserDBMap::iterator it = user_db_map_.find(username_hash); |
| + if (it != user_db_map_.end()) { |
| + if (it->second->ready_) |
| + return it->second; |
| + it->second->OnReady(callback); |
| + return NULL; |
| + } |
| + |
| + crypto::ScopedPK11Slot public_slot( |
| + crypto::GetPublicSlotForChromeOSUser(username_hash)); |
| + if (!public_slot) { |
| + // Invalid user, or someone called us before InitializeNSSForChromeOSUser |
| + // got called for the user. |
| + NOTREACHED(); |
| + return NULL; |
| + } |
| + |
| + DVLOG(1) << "Creating DB for: " << username_hash; |
| + NSSCertDatabaseChromeOS* db = |
| + new NSSCertDatabaseChromeOS(public_slot.Pass()); |
| + user_db_map_[username_hash] = db; |
| + |
| + crypto::ScopedPK11Slot private_slot(crypto::GetPrivateSlotForChromeOSUser( |
| + username_hash, |
| + base::Bind(&NSSCertDatabaseChromeOS::SetPrivateSlot, |
| + base::Unretained(db)))); |
| + if (private_slot) |
| + db->SetPrivateSlot(private_slot.Pass()); |
| + |
| + if (db->ready_) |
| + return db; |
| + |
| + db->OnReady(callback); |
| + return NULL; |
| + } |
| + |
| + void RemoveUserForTesting(const std::string& username_hash) { |
| + DCHECK(CalledOnValidThread()); |
| + UserDBMap::iterator it = user_db_map_.find(username_hash); |
| + if (it == user_db_map_.end()) |
| + return; |
| + delete it->second; |
| + user_db_map_.erase(it); |
| + } |
| + |
| + private: |
| + friend struct base::DefaultLazyInstanceTraits<Manager>; |
| + |
| + Manager() {} |
| + |
| + typedef std::map<std::string, NSSCertDatabaseChromeOS*> UserDBMap; |
| + UserDBMap user_db_map_; |
| +}; |
| + |
| +namespace { |
| +base::LazyInstance<NSSCertDatabaseChromeOS::Manager>::Leaky |
| + g_nss_cert_database_chromeos_manager = LAZY_INSTANCE_INITIALIZER; |
| +} // namespace |
| + |
| +// static |
| +NSSCertDatabase* NSSCertDatabaseChromeOS::GetForUser( |
| + const std::string& username_hash, |
| + const base::Callback<void(NSSCertDatabase*)>& callback) { |
| + return g_nss_cert_database_chromeos_manager.Get().GetForUser(username_hash, |
| + callback); |
| +} |
| + |
| +NSSCertDatabaseChromeOS::NSSCertDatabaseChromeOS( |
| + crypto::ScopedPK11Slot public_slot) |
| + : ready_(false), public_slot_(public_slot.Pass()) {} |
| + |
| +NSSCertDatabaseChromeOS::~NSSCertDatabaseChromeOS() {} |
| + |
| +void NSSCertDatabaseChromeOS::ListCerts(CertificateList* certs) { |
| + DCHECK(ready_); |
| + NSSCertDatabase::ListCerts(certs); |
| + |
| + size_t pre_size = certs->size(); |
| + certs->erase(std::remove_if( |
| + certs->begin(), |
|
Ryan Sleevi
2013/12/13 19:16:59
is this clang-format'd? I would assume it would be
mattm
2013/12/18 04:00:50
Yeah, this is clang-formatted.
|
| + certs->end(), |
| + NSSProfileFilterChromeOS::CertNotAllowedForProfilePredicate( |
| + profile_filter_)), |
| + certs->end()); |
| + DVLOG(1) << "filtered " << pre_size - certs->size() << " of " << pre_size |
| + << " certs"; |
| +} |
| + |
| +crypto::ScopedPK11Slot NSSCertDatabaseChromeOS::GetPublicSlot() const { |
| + return crypto::ScopedPK11Slot( |
| + public_slot_ ? PK11_ReferenceSlot(public_slot_.get()) : NULL); |
| +} |
| + |
| +crypto::ScopedPK11Slot NSSCertDatabaseChromeOS::GetPrivateSlot() const { |
| + return crypto::ScopedPK11Slot( |
| + private_slot_ ? PK11_ReferenceSlot(private_slot_.get()) : NULL); |
| +} |
| + |
| +void NSSCertDatabaseChromeOS::ListModules(CryptoModuleList* modules, |
| + bool need_rw) const { |
| + DCHECK(ready_); |
| + NSSCertDatabase::ListModules(modules, need_rw); |
| + |
| + size_t pre_size = modules->size(); |
| + modules->erase( |
| + std::remove_if( |
| + modules->begin(), |
| + modules->end(), |
| + NSSProfileFilterChromeOS::ModuleNotAllowedForProfilePredicate( |
| + profile_filter_)), |
| + modules->end()); |
| + DVLOG(1) << "filtered " << pre_size - modules->size() << " of " << pre_size |
| + << " modules"; |
| +} |
| + |
| +void NSSCertDatabaseChromeOS::SetPrivateSlot( |
| + crypto::ScopedPK11Slot private_slot) { |
| + DCHECK(!ready_); |
| + if (!private_slot) |
| + LOG(WARNING) << "initializing with NULL private_slot."; |
| + private_slot_ = private_slot.Pass(); |
| + profile_filter_.Init(GetPublicSlot(), GetPrivateSlot()); |
| + ready_ = true; |
| + |
| + ReadyCallbackList callback_list; |
| + callback_list.swap(ready_callback_list_); |
| + for (ReadyCallbackList::iterator i = callback_list.begin(); |
| + i != callback_list.end(); |
| + ++i) { |
| + (*i).Run(this); |
| + } |
| +} |
| + |
| +void NSSCertDatabaseChromeOS::OnReady( |
| + const base::Callback<void(NSSCertDatabase*)>& callback) { |
| + DCHECK(!ready_); |
| + ready_callback_list_.push_back(callback); |
| +} |
| + |
| +// static |
| +void NSSCertDatabaseChromeOS::RemoveUserForTesting( |
| + const std::string& username_hash) { |
| + return g_nss_cert_database_chromeos_manager.Get().RemoveUserForTesting( |
| + username_hash); |
| +} |
| + |
| +} // namespace net |