// Copyright 2013 The Chromium Authors
// 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 <algorithm>
#include <memory>
#include <utility>

#include "base/containers/cxx20_erase.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "net/cert/nss_cert_database.h"

namespace net {

NSSCertDatabaseChromeOS::NSSCertDatabaseChromeOS(
    crypto::ScopedPK11Slot public_slot,
    crypto::ScopedPK11Slot private_slot)
    : NSSCertDatabase(std::move(public_slot), std::move(private_slot)) {
  // By default, don't use a system slot. Only if explicitly set by
  // SetSystemSlot, the system slot will be used.
  profile_filter_.Init(GetPublicSlot(),
                       GetPrivateSlot(),
                       crypto::ScopedPK11Slot() /* no system slot */);
}

NSSCertDatabaseChromeOS::~NSSCertDatabaseChromeOS() = default;

void NSSCertDatabaseChromeOS::SetSystemSlot(
    crypto::ScopedPK11Slot system_slot) {
  system_slot_ = std::move(system_slot);
  profile_filter_.Init(GetPublicSlot(), GetPrivateSlot(), GetSystemSlot());
}

void NSSCertDatabaseChromeOS::ListCerts(
    NSSCertDatabase::ListCertsCallback callback) {
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
      base::BindOnce(&NSSCertDatabaseChromeOS::ListCertsImpl, profile_filter_),
      std::move(callback));
}

void NSSCertDatabaseChromeOS::ListCertsInfo(
    ListCertsInfoCallback callback,
    NSSRootsHandling nss_roots_handling) {
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
      base::BindOnce(&NSSCertDatabaseChromeOS::ListCertsInfoImpl,
                     profile_filter_, /*slot=*/GetSystemSlot(),
                     /*add_certs_info=*/true, nss_roots_handling),
      std::move(callback));
}

crypto::ScopedPK11Slot NSSCertDatabaseChromeOS::GetSystemSlot() const {
  if (system_slot_)
    return crypto::ScopedPK11Slot(PK11_ReferenceSlot(system_slot_.get()));
  return crypto::ScopedPK11Slot();
}

void NSSCertDatabaseChromeOS::ListModules(
    std::vector<crypto::ScopedPK11Slot>* modules,
    bool need_rw) const {
  NSSCertDatabase::ListModules(modules, need_rw);

  const NSSProfileFilterChromeOS& profile_filter = profile_filter_;
  base::EraseIf(*modules, [&profile_filter](crypto::ScopedPK11Slot& module) {
    return !profile_filter.IsModuleAllowed(module.get());
  });
}

bool NSSCertDatabaseChromeOS::SetCertTrust(CERTCertificate* cert,
                                           CertType type,
                                           TrustBits trust_bits) {
  crypto::ScopedPK11Slot public_slot = GetPublicSlot();

  // Ensure that the certificate exists on the public slot so NSS puts the trust
  // settings there (https://crbug.com/1132030).
  if (public_slot == GetSystemSlot()) {
    // Never attempt to store trust setting on the system slot.
    return false;
  }

  if (!IsCertificateOnSlot(cert, public_slot.get())) {
    // Copy the certificate to the public slot.
    SECStatus srv =
        PK11_ImportCert(public_slot.get(), cert, CK_INVALID_HANDLE,
                        cert->nickname, PR_FALSE /* includeTrust (unused) */);
    if (srv != SECSuccess) {
      LOG(ERROR) << "Failed to import certificate onto public slot.";
      return false;
    }
  }
  return NSSCertDatabase::SetCertTrust(cert, type, trust_bits);
}

// static
ScopedCERTCertificateList NSSCertDatabaseChromeOS::ListCertsImpl(
    const NSSProfileFilterChromeOS& profile_filter) {
  CertInfoList certs_info =
      ListCertsInfoImpl(profile_filter, crypto::ScopedPK11Slot(),
                        /*add_certs_info=*/false, NSSRootsHandling::kInclude);

  return ExtractCertificates(std::move(certs_info));
}

// static
NSSCertDatabase::CertInfoList NSSCertDatabaseChromeOS::ListCertsInfoImpl(
    const NSSProfileFilterChromeOS& profile_filter,
    crypto::ScopedPK11Slot system_slot,
    bool add_certs_info,
    NSSRootsHandling nss_roots_handling) {
  // This method may acquire the NSS lock or reenter this code via extension
  // hooks (such as smart card UI). To ensure threads are not starved or
  // deadlocked, the base::ScopedBlockingCall below increments the thread pool
  // capacity if this method takes too much time to run.
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  CertInfoList certs_info(NSSCertDatabase::ListCertsInfoImpl(
      crypto::ScopedPK11Slot(), add_certs_info, nss_roots_handling));

  // Filter certificate information according to user profile.
  base::EraseIf(certs_info, [&profile_filter](CertInfo& cert_info) {
    return !profile_filter.IsCertAllowed(cert_info.cert.get());
  });

  if (add_certs_info) {
    // Add Chrome OS specific information.
    for (auto& cert_info : certs_info) {
      cert_info.device_wide =
          IsCertificateOnSlot(cert_info.cert.get(), system_slot.get());
      cert_info.hardware_backed = IsHardwareBacked(cert_info.cert.get());
    }
  }

  return certs_info;
}

}  // namespace net
