1// Copyright 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 "net/ssl/client_cert_store_chromeos.h" 6 7#include <cert.h> 8 9#include "base/bind.h" 10#include "crypto/nss_crypto_module_delegate.h" 11#include "crypto/nss_util_internal.h" 12 13namespace net { 14 15namespace { 16 17typedef base::Callback<void(crypto::ScopedPK11Slot system_slot, 18 crypto::ScopedPK11Slot private_slot)> 19 GetSystemAndPrivateSlotCallback; 20 21// Gets the private slot for the user with the username hash |username_hash| and 22// calls |callback| with both |system_slot| and the obtained private slot. 23void GetPrivateSlotAndCallBack(const std::string& username_hash, 24 const GetSystemAndPrivateSlotCallback& callback, 25 crypto::ScopedPK11Slot system_slot) { 26 base::Callback<void(crypto::ScopedPK11Slot)> wrapped_callback = 27 base::Bind(callback, base::Passed(&system_slot)); 28 29 crypto::ScopedPK11Slot slot( 30 crypto::GetPrivateSlotForChromeOSUser(username_hash, wrapped_callback)); 31 if (slot) 32 wrapped_callback.Run(slot.Pass()); 33} 34 35// Gets the system slot, then the private slot for the user with the username 36// hash |username_hash|, and finally calls |callback| with both slots. 37void GetSystemAndPrivateSlot(const std::string& username_hash, 38 const GetSystemAndPrivateSlotCallback& callback) { 39 crypto::ScopedPK11Slot system_slot(crypto::GetSystemNSSKeySlot( 40 base::Bind(&GetPrivateSlotAndCallBack, username_hash, callback))); 41 if (system_slot) 42 GetPrivateSlotAndCallBack(username_hash, callback, system_slot.Pass()); 43} 44 45} // namespace 46 47ClientCertStoreChromeOS::ClientCertStoreChromeOS( 48 bool use_system_slot, 49 const std::string& username_hash, 50 const PasswordDelegateFactory& password_delegate_factory) 51 : ClientCertStoreNSS(password_delegate_factory), 52 use_system_slot_(use_system_slot), 53 username_hash_(username_hash) { 54} 55 56ClientCertStoreChromeOS::~ClientCertStoreChromeOS() {} 57 58void ClientCertStoreChromeOS::GetClientCerts( 59 const SSLCertRequestInfo& cert_request_info, 60 CertificateList* selected_certs, 61 const base::Closure& callback) { 62 GetSystemAndPrivateSlotCallback bound_callback = 63 base::Bind(&ClientCertStoreChromeOS::DidGetSystemAndPrivateSlot, 64 // Caller is responsible for keeping the ClientCertStore alive 65 // until the callback is run. 66 base::Unretained(this), 67 &cert_request_info, 68 selected_certs, 69 callback); 70 71 if (use_system_slot_) { 72 GetSystemAndPrivateSlot(username_hash_, bound_callback); 73 } else { 74 // Skip getting the system slot. 75 GetPrivateSlotAndCallBack( 76 username_hash_, bound_callback, crypto::ScopedPK11Slot()); 77 } 78} 79 80void ClientCertStoreChromeOS::GetClientCertsImpl( 81 CERTCertList* cert_list, 82 const SSLCertRequestInfo& request, 83 bool query_nssdb, 84 CertificateList* selected_certs) { 85 ClientCertStoreNSS::GetClientCertsImpl( 86 cert_list, request, query_nssdb, selected_certs); 87 88 size_t pre_size = selected_certs->size(); 89 selected_certs->erase( 90 std::remove_if( 91 selected_certs->begin(), 92 selected_certs->end(), 93 NSSProfileFilterChromeOS::CertNotAllowedForProfilePredicate( 94 profile_filter_)), 95 selected_certs->end()); 96 DVLOG(1) << "filtered " << pre_size - selected_certs->size() << " of " 97 << pre_size << " certs"; 98} 99 100void ClientCertStoreChromeOS::DidGetSystemAndPrivateSlot( 101 const SSLCertRequestInfo* request, 102 CertificateList* selected_certs, 103 const base::Closure& callback, 104 crypto::ScopedPK11Slot system_slot, 105 crypto::ScopedPK11Slot private_slot) { 106 profile_filter_.Init(crypto::GetPublicSlotForChromeOSUser(username_hash_), 107 private_slot.Pass(), 108 system_slot.Pass()); 109 ClientCertStoreNSS::GetClientCerts(*request, selected_certs, callback); 110} 111 112} // namespace net 113