15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/ssl/client_cert_store_chromeos.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <cert.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/nss_crypto_module_delegate.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "crypto/nss_util_internal.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)typedef base::Callback<void(crypto::ScopedPK11Slot system_slot,
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            crypto::ScopedPK11Slot private_slot)>
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GetSystemAndPrivateSlotCallback;
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Gets the private slot for the user with the username hash |username_hash| and
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// calls |callback| with both |system_slot| and the obtained private slot.
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GetPrivateSlotAndCallBack(const std::string& username_hash,
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const GetSystemAndPrivateSlotCallback& callback,
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               crypto::ScopedPK11Slot system_slot) {
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::Callback<void(crypto::ScopedPK11Slot)> wrapped_callback =
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(callback, base::Passed(&system_slot));
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedPK11Slot slot(
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      crypto::GetPrivateSlotForChromeOSUser(username_hash, wrapped_callback));
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (slot)
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    wrapped_callback.Run(slot.Pass());
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Gets the system slot, then the private slot for the user with the username
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// hash |username_hash|, and finally calls |callback| with both slots.
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GetSystemAndPrivateSlot(const std::string& username_hash,
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             const GetSystemAndPrivateSlotCallback& callback) {
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  crypto::ScopedPK11Slot system_slot(crypto::GetSystemNSSKeySlot(
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&GetPrivateSlotAndCallBack, username_hash, callback)));
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (system_slot)
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GetPrivateSlotAndCallBack(username_hash, callback, system_slot.Pass());
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ClientCertStoreChromeOS::ClientCertStoreChromeOS(
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool use_system_slot,
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& username_hash,
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const PasswordDelegateFactory& password_delegate_factory)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : ClientCertStoreNSS(password_delegate_factory),
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      use_system_slot_(use_system_slot),
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      username_hash_(username_hash) {
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ClientCertStoreChromeOS::~ClientCertStoreChromeOS() {}
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ClientCertStoreChromeOS::GetClientCerts(
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SSLCertRequestInfo& cert_request_info,
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CertificateList* selected_certs,
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Closure& callback) {
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  GetSystemAndPrivateSlotCallback bound_callback =
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&ClientCertStoreChromeOS::DidGetSystemAndPrivateSlot,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 // Caller is responsible for keeping the ClientCertStore alive
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 // until the callback is run.
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(this),
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 &cert_request_info,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 selected_certs,
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 callback);
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (use_system_slot_) {
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GetSystemAndPrivateSlot(username_hash_, bound_callback);
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Skip getting the system slot.
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    GetPrivateSlotAndCallBack(
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        username_hash_, bound_callback, crypto::ScopedPK11Slot());
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ClientCertStoreChromeOS::GetClientCertsImpl(
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CERTCertList* cert_list,
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const SSLCertRequestInfo& request,
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool query_nssdb,
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    CertificateList* selected_certs) {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClientCertStoreNSS::GetClientCertsImpl(
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      cert_list, request, query_nssdb, selected_certs);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  size_t pre_size = selected_certs->size();
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  selected_certs->erase(
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::remove_if(
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          selected_certs->begin(),
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          selected_certs->end(),
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          NSSProfileFilterChromeOS::CertNotAllowedForProfilePredicate(
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              profile_filter_)),
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      selected_certs->end());
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DVLOG(1) << "filtered " << pre_size - selected_certs->size() << " of "
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)           << pre_size << " certs";
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ClientCertStoreChromeOS::DidGetSystemAndPrivateSlot(
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SSLCertRequestInfo* request,
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CertificateList* selected_certs,
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Closure& callback,
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    crypto::ScopedPK11Slot system_slot,
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    crypto::ScopedPK11Slot private_slot) {
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  profile_filter_.Init(crypto::GetPublicSlotForChromeOSUser(username_hash_),
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       private_slot.Pass(),
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       system_slot.Pass());
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ClientCertStoreNSS::GetClientCerts(*request, selected_certs, callback);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
113