// Copyright (c) 2012 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.h"

#include <cert.h>
#include <certdb.h>
#include <keyhi.h>
#include <pk11pub.h>
#include <secmod.h>

#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "base/threading/worker_pool.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/crypto_module.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_database.h"
#include "net/cert/x509_certificate.h"
#include "net/third_party/mozilla_security_manager/nsNSSCertificateDB.h"
#include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h"

// In NSS 3.13, CERTDB_VALID_PEER was renamed CERTDB_TERMINAL_RECORD. So we use
// the new name of the macro.
#if !defined(CERTDB_TERMINAL_RECORD)
#define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
#endif

// PSM = Mozilla's Personal Security Manager.
namespace psm = mozilla_security_manager;

namespace net {

namespace {

// TODO(pneubeck): Move this class out of NSSCertDatabase and to the caller of
// the c'tor of NSSCertDatabase, see https://crbug.com/395983 .
// Helper that observes events from the NSSCertDatabase and forwards them to
// the given CertDatabase.
class CertNotificationForwarder : public NSSCertDatabase::Observer {
 public:
  explicit CertNotificationForwarder(CertDatabase* cert_db)
      : cert_db_(cert_db) {}

  ~CertNotificationForwarder() override {}

  // NSSCertDatabase::Observer implementation:
  void OnCertAdded(const X509Certificate* cert) override {
    cert_db_->NotifyObserversOfCertAdded(cert);
  }

  void OnCertRemoved(const X509Certificate* cert) override {
    cert_db_->NotifyObserversOfCertRemoved(cert);
  }

  void OnCACertChanged(const X509Certificate* cert) override {
    cert_db_->NotifyObserversOfCACertChanged(cert);
  }

 private:
  CertDatabase* cert_db_;

  DISALLOW_COPY_AND_ASSIGN(CertNotificationForwarder);
};

}  // namespace

NSSCertDatabase::ImportCertFailure::ImportCertFailure(
    const scoped_refptr<X509Certificate>& cert,
    int err)
    : certificate(cert), net_error(err) {}

NSSCertDatabase::ImportCertFailure::~ImportCertFailure() {}

NSSCertDatabase::NSSCertDatabase(crypto::ScopedPK11Slot public_slot,
                                 crypto::ScopedPK11Slot private_slot)
    : public_slot_(public_slot.Pass()),
      private_slot_(private_slot.Pass()),
      observer_list_(new ObserverListThreadSafe<Observer>),
      weak_factory_(this) {
  CHECK(public_slot_);

  // This also makes sure that NSS has been initialized.
  CertDatabase* cert_db = CertDatabase::GetInstance();
  cert_notification_forwarder_.reset(new CertNotificationForwarder(cert_db));
  AddObserver(cert_notification_forwarder_.get());

  psm::EnsurePKCS12Init();
}

NSSCertDatabase::~NSSCertDatabase() {}

void NSSCertDatabase::ListCertsSync(CertificateList* certs) {
  ListCertsImpl(crypto::ScopedPK11Slot(), certs);
}

void NSSCertDatabase::ListCerts(
    const base::Callback<void(scoped_ptr<CertificateList> certs)>& callback) {
  scoped_ptr<CertificateList> certs(new CertificateList());

  // base::Passed will NULL out |certs|, so cache the underlying pointer here.
  CertificateList* raw_certs = certs.get();
  GetSlowTaskRunner()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&NSSCertDatabase::ListCertsImpl,
                 base::Passed(crypto::ScopedPK11Slot()),
                 base::Unretained(raw_certs)),
      base::Bind(callback, base::Passed(&certs)));
}

void NSSCertDatabase::ListCertsInSlot(const ListCertsCallback& callback,
                                      PK11SlotInfo* slot) {
  DCHECK(slot);
  scoped_ptr<CertificateList> certs(new CertificateList());

  // base::Passed will NULL out |certs|, so cache the underlying pointer here.
  CertificateList* raw_certs = certs.get();
  GetSlowTaskRunner()->PostTaskAndReply(
      FROM_HERE,
      base::Bind(&NSSCertDatabase::ListCertsImpl,
                 base::Passed(crypto::ScopedPK11Slot(PK11_ReferenceSlot(slot))),
                 base::Unretained(raw_certs)),
      base::Bind(callback, base::Passed(&certs)));
}

#if defined(OS_CHROMEOS)
crypto::ScopedPK11Slot NSSCertDatabase::GetSystemSlot() const {
  return crypto::ScopedPK11Slot();
}
#endif

crypto::ScopedPK11Slot NSSCertDatabase::GetPublicSlot() const {
  return crypto::ScopedPK11Slot(PK11_ReferenceSlot(public_slot_.get()));
}

crypto::ScopedPK11Slot NSSCertDatabase::GetPrivateSlot() const {
  if (!private_slot_)
    return crypto::ScopedPK11Slot();
  return crypto::ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()));
}

CryptoModule* NSSCertDatabase::GetPublicModule() const {
  crypto::ScopedPK11Slot slot(GetPublicSlot());
  return CryptoModule::CreateFromHandle(slot.get());
}

CryptoModule* NSSCertDatabase::GetPrivateModule() const {
  crypto::ScopedPK11Slot slot(GetPrivateSlot());
  return CryptoModule::CreateFromHandle(slot.get());
}

void NSSCertDatabase::ListModules(CryptoModuleList* modules,
                                  bool need_rw) const {
  modules->clear();

  // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc.
  crypto::ScopedPK11SlotList slot_list(
      PK11_GetAllTokens(CKM_INVALID_MECHANISM,
                        need_rw ? PR_TRUE : PR_FALSE,  // needRW
                        PR_TRUE,                       // loadCerts (unused)
                        NULL));                        // wincx
  if (!slot_list) {
    LOG(ERROR) << "PK11_GetAllTokens failed: " << PORT_GetError();
    return;
  }

  PK11SlotListElement* slot_element = PK11_GetFirstSafe(slot_list.get());
  while (slot_element) {
    modules->push_back(CryptoModule::CreateFromHandle(slot_element->slot));
    slot_element = PK11_GetNextSafe(slot_list.get(), slot_element,
                                    PR_FALSE);  // restart
  }
}

int NSSCertDatabase::ImportFromPKCS12(CryptoModule* module,
                                      const std::string& data,
                                      const base::string16& password,
                                      bool is_extractable,
                                      CertificateList* imported_certs) {
  DVLOG(1) << __func__ << " "
           << PK11_GetModuleID(module->os_module_handle()) << ":"
           << PK11_GetSlotID(module->os_module_handle());
  int result = psm::nsPKCS12Blob_Import(module->os_module_handle(),
                                        data.data(), data.size(),
                                        password,
                                        is_extractable,
                                        imported_certs);
  if (result == OK)
    NotifyObserversOfCertAdded(NULL);

  return result;
}

int NSSCertDatabase::ExportToPKCS12(
    const CertificateList& certs,
    const base::string16& password,
    std::string* output) const {
  return psm::nsPKCS12Blob_Export(output, certs, password);
}

X509Certificate* NSSCertDatabase::FindRootInList(
    const CertificateList& certificates) const {
  DCHECK_GT(certificates.size(), 0U);

  if (certificates.size() == 1)
    return certificates[0].get();

  X509Certificate* cert0 = certificates[0].get();
  X509Certificate* cert1 = certificates[1].get();
  X509Certificate* certn_2 = certificates[certificates.size() - 2].get();
  X509Certificate* certn_1 = certificates[certificates.size() - 1].get();

  if (CERT_CompareName(&cert1->os_cert_handle()->issuer,
                       &cert0->os_cert_handle()->subject) == SECEqual)
    return cert0;
  if (CERT_CompareName(&certn_2->os_cert_handle()->issuer,
                       &certn_1->os_cert_handle()->subject) == SECEqual)
    return certn_1;

  LOG(WARNING) << "certificate list is not a hierarchy";
  return cert0;
}

bool NSSCertDatabase::ImportCACerts(const CertificateList& certificates,
                                    TrustBits trust_bits,
                                    ImportCertFailureList* not_imported) {
  crypto::ScopedPK11Slot slot(GetPublicSlot());
  X509Certificate* root = FindRootInList(certificates);
  bool success = psm::ImportCACerts(
      slot.get(), certificates, root, trust_bits, not_imported);
  if (success)
    NotifyObserversOfCACertChanged(NULL);

  return success;
}

bool NSSCertDatabase::ImportServerCert(const CertificateList& certificates,
                                       TrustBits trust_bits,
                                       ImportCertFailureList* not_imported) {
  crypto::ScopedPK11Slot slot(GetPublicSlot());
  return psm::ImportServerCert(
      slot.get(), certificates, trust_bits, not_imported);
}

NSSCertDatabase::TrustBits NSSCertDatabase::GetCertTrust(
    const X509Certificate* cert,
    CertType type) const {
  CERTCertTrust trust;
  SECStatus srv = CERT_GetCertTrust(cert->os_cert_handle(), &trust);
  if (srv != SECSuccess) {
    LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError();
    return TRUST_DEFAULT;
  }
  // We define our own more "friendly" TrustBits, which means we aren't able to
  // round-trip all possible NSS trust flag combinations.  We try to map them in
  // a sensible way.
  switch (type) {
    case CA_CERT: {
      const unsigned kTrustedCA = CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
      const unsigned kCAFlags = kTrustedCA | CERTDB_TERMINAL_RECORD;

      TrustBits trust_bits = TRUST_DEFAULT;
      if ((trust.sslFlags & kCAFlags) == CERTDB_TERMINAL_RECORD)
        trust_bits |= DISTRUSTED_SSL;
      else if (trust.sslFlags & kTrustedCA)
        trust_bits |= TRUSTED_SSL;

      if ((trust.emailFlags & kCAFlags) == CERTDB_TERMINAL_RECORD)
        trust_bits |= DISTRUSTED_EMAIL;
      else if (trust.emailFlags & kTrustedCA)
        trust_bits |= TRUSTED_EMAIL;

      if ((trust.objectSigningFlags & kCAFlags) == CERTDB_TERMINAL_RECORD)
        trust_bits |= DISTRUSTED_OBJ_SIGN;
      else if (trust.objectSigningFlags & kTrustedCA)
        trust_bits |= TRUSTED_OBJ_SIGN;

      return trust_bits;
    }
    case SERVER_CERT:
      if (trust.sslFlags & CERTDB_TERMINAL_RECORD) {
        if (trust.sslFlags & CERTDB_TRUSTED)
          return TRUSTED_SSL;
        return DISTRUSTED_SSL;
      }
      return TRUST_DEFAULT;
    default:
      return TRUST_DEFAULT;
  }
}

bool NSSCertDatabase::IsUntrusted(const X509Certificate* cert) const {
  CERTCertTrust nsstrust;
  SECStatus rv = CERT_GetCertTrust(cert->os_cert_handle(), &nsstrust);
  if (rv != SECSuccess) {
    LOG(ERROR) << "CERT_GetCertTrust failed with error " << PORT_GetError();
    return false;
  }

  // The CERTCertTrust structure contains three trust records:
  // sslFlags, emailFlags, and objectSigningFlags.  The three
  // trust records are independent of each other.
  //
  // If the CERTDB_TERMINAL_RECORD bit in a trust record is set,
  // then that trust record is a terminal record.  A terminal
  // record is used for explicit trust and distrust of an
  // end-entity or intermediate CA cert.
  //
  // In a terminal record, if neither CERTDB_TRUSTED_CA nor
  // CERTDB_TRUSTED is set, then the terminal record means
  // explicit distrust.  On the other hand, if the terminal
  // record has either CERTDB_TRUSTED_CA or CERTDB_TRUSTED bit
  // set, then the terminal record means explicit trust.
  //
  // For a root CA, the trust record does not have
  // the CERTDB_TERMINAL_RECORD bit set.

  static const unsigned int kTrusted = CERTDB_TRUSTED_CA | CERTDB_TRUSTED;
  if ((nsstrust.sslFlags & CERTDB_TERMINAL_RECORD) != 0 &&
      (nsstrust.sslFlags & kTrusted) == 0) {
    return true;
  }
  if ((nsstrust.emailFlags & CERTDB_TERMINAL_RECORD) != 0 &&
      (nsstrust.emailFlags & kTrusted) == 0) {
    return true;
  }
  if ((nsstrust.objectSigningFlags & CERTDB_TERMINAL_RECORD) != 0 &&
      (nsstrust.objectSigningFlags & kTrusted) == 0) {
    return true;
  }

  // Self-signed certificates that don't have any trust bits set are untrusted.
  // Other certificates that don't have any trust bits set may still be trusted
  // if they chain up to a trust anchor.
  if (CERT_CompareName(&cert->os_cert_handle()->issuer,
                       &cert->os_cert_handle()->subject) == SECEqual) {
    return (nsstrust.sslFlags & kTrusted) == 0 &&
           (nsstrust.emailFlags & kTrusted) == 0 &&
           (nsstrust.objectSigningFlags & kTrusted) == 0;
  }

  return false;
}

bool NSSCertDatabase::SetCertTrust(const X509Certificate* cert,
                                CertType type,
                                TrustBits trust_bits) {
  bool success = psm::SetCertTrust(cert, type, trust_bits);
  if (success)
    NotifyObserversOfCACertChanged(cert);

  return success;
}

bool NSSCertDatabase::DeleteCertAndKey(X509Certificate* cert) {
  if (!DeleteCertAndKeyImpl(cert))
    return false;
  NotifyObserversOfCertRemoved(cert);
  return true;
}

void NSSCertDatabase::DeleteCertAndKeyAsync(
    const scoped_refptr<X509Certificate>& cert,
    const DeleteCertCallback& callback) {
  base::PostTaskAndReplyWithResult(
      GetSlowTaskRunner().get(),
      FROM_HERE,
      base::Bind(&NSSCertDatabase::DeleteCertAndKeyImpl, cert),
      base::Bind(&NSSCertDatabase::NotifyCertRemovalAndCallBack,
                 weak_factory_.GetWeakPtr(),
                 cert,
                 callback));
}

bool NSSCertDatabase::IsReadOnly(const X509Certificate* cert) const {
  PK11SlotInfo* slot = cert->os_cert_handle()->slot;
  return slot && PK11_IsReadOnly(slot);
}

bool NSSCertDatabase::IsHardwareBacked(const X509Certificate* cert) const {
  PK11SlotInfo* slot = cert->os_cert_handle()->slot;
  return slot && PK11_IsHW(slot);
}

void NSSCertDatabase::AddObserver(Observer* observer) {
  observer_list_->AddObserver(observer);
}

void NSSCertDatabase::RemoveObserver(Observer* observer) {
  observer_list_->RemoveObserver(observer);
}

void NSSCertDatabase::SetSlowTaskRunnerForTest(
    const scoped_refptr<base::TaskRunner>& task_runner) {
  slow_task_runner_for_test_ = task_runner;
}

// static
void NSSCertDatabase::ListCertsImpl(crypto::ScopedPK11Slot slot,
                                    CertificateList* certs) {
  certs->clear();

  CERTCertList* cert_list = NULL;
  if (slot)
    cert_list = PK11_ListCertsInSlot(slot.get());
  else
    cert_list = PK11_ListCerts(PK11CertListUnique, NULL);

  CERTCertListNode* node;
  for (node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(node, cert_list);
       node = CERT_LIST_NEXT(node)) {
    certs->push_back(X509Certificate::CreateFromHandle(
        node->cert, X509Certificate::OSCertHandles()));
  }
  CERT_DestroyCertList(cert_list);
}

scoped_refptr<base::TaskRunner> NSSCertDatabase::GetSlowTaskRunner() const {
  if (slow_task_runner_for_test_.get())
    return slow_task_runner_for_test_;
  return base::WorkerPool::GetTaskRunner(true /*task is slow*/);
}

void NSSCertDatabase::NotifyCertRemovalAndCallBack(
    scoped_refptr<X509Certificate> cert,
    const DeleteCertCallback& callback,
    bool success) {
  if (success)
    NotifyObserversOfCertRemoved(cert.get());
  callback.Run(success);
}

void NSSCertDatabase::NotifyObserversOfCertAdded(const X509Certificate* cert) {
  observer_list_->Notify(FROM_HERE, &Observer::OnCertAdded,
                         make_scoped_refptr(cert));
}

void NSSCertDatabase::NotifyObserversOfCertRemoved(
    const X509Certificate* cert) {
  observer_list_->Notify(FROM_HERE, &Observer::OnCertRemoved,
                         make_scoped_refptr(cert));
}

void NSSCertDatabase::NotifyObserversOfCACertChanged(
    const X509Certificate* cert) {
  observer_list_->Notify(FROM_HERE, &Observer::OnCACertChanged,
                         make_scoped_refptr(cert));
}

// static
bool NSSCertDatabase::DeleteCertAndKeyImpl(
    scoped_refptr<X509Certificate> cert) {
  // For some reason, PK11_DeleteTokenCertAndKey only calls
  // SEC_DeletePermCertificate if the private key is found.  So, we check
  // whether a private key exists before deciding which function to call to
  // delete the cert.
  SECKEYPrivateKey* privKey =
      PK11_FindKeyByAnyCert(cert->os_cert_handle(), NULL);
  if (privKey) {
    SECKEY_DestroyPrivateKey(privKey);
    if (PK11_DeleteTokenCertAndKey(cert->os_cert_handle(), NULL)) {
      LOG(ERROR) << "PK11_DeleteTokenCertAndKey failed: " << PORT_GetError();
      return false;
    }
  } else {
    if (SEC_DeletePermCertificate(cert->os_cert_handle())) {
      LOG(ERROR) << "SEC_DeletePermCertificate failed: " << PORT_GetError();
      return false;
    }
  }
  return true;
}

}  // namespace net
