// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "crypto/nss_util.h"

#include <nss.h>
#include <pk11pub.h>
#include <plarena.h>
#include <prerror.h>
#include <prinit.h>
#include <prtime.h>
#include <secmod.h>

#include <map>
#include <memory>
#include <utility>

#include "base/callback_list.h"
#include "base/debug/stack_trace.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "crypto/chaps_support.h"
#include "crypto/nss_util_internal.h"

namespace crypto {

namespace {

const char kUserNSSDatabaseName[] = "UserNSSDB";

class ChromeOSUserData {
 public:
  using SlotReadyCallback = base::OnceCallback<void(ScopedPK11Slot)>;

  explicit ChromeOSUserData(ScopedPK11Slot public_slot)
      : public_slot_(std::move(public_slot)) {}

  ~ChromeOSUserData() {
    if (public_slot_) {
      SECStatus status = CloseSoftwareNSSDB(public_slot_.get());
      if (status != SECSuccess)
        PLOG(ERROR) << "CloseSoftwareNSSDB failed: " << PORT_GetError();
    }
  }

  ScopedPK11Slot GetPublicSlot() {
    return ScopedPK11Slot(public_slot_ ? PK11_ReferenceSlot(public_slot_.get())
                                       : nullptr);
  }

  ScopedPK11Slot GetPrivateSlot(SlotReadyCallback callback) {
    if (private_slot_)
      return ScopedPK11Slot(PK11_ReferenceSlot(private_slot_.get()));
    if (!callback.is_null()) {
      // Callback lists cannot hold callbacks that take move-only args, since
      // Notify()ing such a list would move the arg into the first callback,
      // leaving it null or unspecified for remaining callbacks.  Instead, adapt
      // the provided callbacks to accept a raw pointer, which can be copied,
      // and then wrap in a separate scoping object for each callback.
      tpm_ready_callback_list_.AddUnsafe(base::BindOnce(
          [](SlotReadyCallback callback, PK11SlotInfo* info) {
            std::move(callback).Run(ScopedPK11Slot(PK11_ReferenceSlot(info)));
          },
          std::move(callback)));
    }
    return ScopedPK11Slot();
  }

  void SetPrivateSlot(ScopedPK11Slot private_slot) {
    DCHECK(!private_slot_);
    private_slot_ = std::move(private_slot);
    tpm_ready_callback_list_.Notify(private_slot_.get());
  }

  bool private_slot_initialization_started() const {
    return private_slot_initialization_started_;
  }

  void set_private_slot_initialization_started() {
    private_slot_initialization_started_ = true;
  }

 private:
  using SlotReadyCallbackList = base::OnceCallbackList<void(PK11SlotInfo*)>;

  ScopedPK11Slot public_slot_;
  ScopedPK11Slot private_slot_;

  bool private_slot_initialization_started_ = false;

  SlotReadyCallbackList tpm_ready_callback_list_;
};

// Contains state used for the ChromeOSTokenManager. Unlike the
// ChromeOSTokenManager, which is thread-checked, this object may live
// and be accessed on multiple threads. While this is normally dangerous,
// this is done to support callers initializing early in process startup,
// where the threads using the objects may not be created yet, and the
// thread startup may depend on these objects.
// Put differently: They may be written to from any thread, if, and only
// if, the thread they will be read from has not yet been created;
// otherwise, this should be treated as thread-affine/thread-hostile.
struct ChromeOSTokenManagerDataForTesting {
  static ChromeOSTokenManagerDataForTesting& GetInstance() {
    static base::NoDestructor<ChromeOSTokenManagerDataForTesting> instance;
    return *instance;
  }

  // System slot that will be used for the system slot initialization.
  ScopedPK11Slot test_system_slot;
};

class ChromeOSTokenManager {
 public:
  enum class State {
    // Initial state.
    kInitializationNotStarted,
    // Initialization of the TPM token was started.
    kInitializationStarted,
    // TPM token was successfully initialized, but not available to the class'
    // users yet.
    kTpmTokenInitialized,
    // TPM token was successfully enabled. It is a final state.
    kTpmTokenEnabled,
    // TPM token will never be enabled. It is a final state.
    kTpmTokenDisabled,
  };

  // Used with PostTaskAndReply to pass handles to worker thread and back.
  struct TPMModuleAndSlot {
    explicit TPMModuleAndSlot(SECMODModule* init_chaps_module)
        : chaps_module(init_chaps_module) {}

    raw_ptr<SECMODModule, ExperimentalAsh> chaps_module;
    ScopedPK11Slot tpm_slot;
  };

  ScopedPK11Slot OpenPersistentNSSDBForPath(const std::string& db_name,
                                            const base::FilePath& path) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    // NSS is allowed to do IO on the current thread since dispatching
    // to a dedicated thread would still have the affect of blocking
    // the current thread, due to NSS's internal locking requirements
    ScopedAllowBlockingForNSS allow_blocking;

    base::FilePath nssdb_path = GetSoftwareNSSDBPath(path);
    if (!base::CreateDirectory(nssdb_path)) {
      LOG(ERROR) << "Failed to create " << nssdb_path.value() << " directory.";
      return ScopedPK11Slot();
    }
    return OpenSoftwareNSSDB(nssdb_path, db_name);
  }

  void InitializeTPMTokenAndSystemSlot(
      int system_slot_id,
      base::OnceCallback<void(bool)> callback) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK_EQ(state_, State::kInitializationNotStarted);
    state_ = State::kInitializationStarted;

    // Note that a reference is not taken to chaps_module_. This is safe since
    // ChromeOSTokenManager is Leaky, so the reference it holds is never
    // released.
    std::unique_ptr<TPMModuleAndSlot> tpm_args(
        new TPMModuleAndSlot(chaps_module_));
    TPMModuleAndSlot* tpm_args_ptr = tpm_args.get();
    base::ThreadPool::PostTaskAndReply(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
        base::BindOnce(&ChromeOSTokenManager::InitializeTPMTokenInThreadPool,
                       system_slot_id, tpm_args_ptr),
        base::BindOnce(
            &ChromeOSTokenManager::OnInitializedTPMTokenAndSystemSlot,
            base::Unretained(this),  // ChromeOSTokenManager is leaky
            std::move(callback), std::move(tpm_args)));
  }

  void FinishInitializingTPMTokenAndSystemSlot() {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!IsInitializationFinished());

    // If `OnInitializedTPMTokenAndSystemSlot` was not called, but a test system
    // slot is prepared, start using it now. Can happen in tests that don't fake
    // enable TPM.
    if (!system_slot_ &&
        ChromeOSTokenManagerDataForTesting::GetInstance().test_system_slot) {
      system_slot_ = ScopedPK11Slot(
          PK11_ReferenceSlot(ChromeOSTokenManagerDataForTesting::GetInstance()
                                 .test_system_slot.get()));
    }

    state_ = (state_ == State::kTpmTokenInitialized) ? State::kTpmTokenEnabled
                                                     : State::kTpmTokenDisabled;

    tpm_ready_callback_list_->Notify();
  }

  static void InitializeTPMTokenInThreadPool(CK_SLOT_ID token_slot_id,
                                             TPMModuleAndSlot* tpm_args) {
    // NSS functions may reenter //net via extension hooks. If the reentered
    // code needs to synchronously wait for a task to run but the thread pool in
    // which that task must run doesn't have enough threads to schedule it, a
    // deadlock occurs. To prevent that, the base::ScopedBlockingCall below
    // increments the thread pool capacity for the duration of the TPM
    // initialization.
    base::ScopedBlockingCall scoped_blocking_call(
        FROM_HERE, base::BlockingType::WILL_BLOCK);

    if (!tpm_args->chaps_module) {
      tpm_args->chaps_module = LoadChaps();
    }
    if (tpm_args->chaps_module) {
      tpm_args->tpm_slot = GetChapsSlot(tpm_args->chaps_module, token_slot_id);
    }
  }

  void OnInitializedTPMTokenAndSystemSlot(
      base::OnceCallback<void(bool)> callback,
      std::unique_ptr<TPMModuleAndSlot> tpm_args) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DVLOG(2) << "Loaded chaps: " << !!tpm_args->chaps_module
             << ", got tpm slot: " << !!tpm_args->tpm_slot;

    chaps_module_ = tpm_args->chaps_module;

    if (ChromeOSTokenManagerDataForTesting::GetInstance().test_system_slot) {
      // chromeos_unittests try to test the TPM initialization process. If we
      // have a test DB open, pretend that it is the system slot.
      system_slot_ = ScopedPK11Slot(
          PK11_ReferenceSlot(ChromeOSTokenManagerDataForTesting::GetInstance()
                                 .test_system_slot.get()));
    } else {
      system_slot_ = std::move(tpm_args->tpm_slot);
    }

    if (system_slot_) {
      state_ = State::kTpmTokenInitialized;
    }

    std::move(callback).Run(!!system_slot_);
  }

  void IsTPMTokenEnabled(base::OnceCallback<void(bool)> callback) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(!callback.is_null());

    if (!IsInitializationFinished()) {
      // Call back to this method when initialization is finished.
      tpm_ready_callback_list_->AddUnsafe(
          base::BindOnce(&ChromeOSTokenManager::IsTPMTokenEnabled,
                         base::Unretained(this) /* singleton is leaky */,
                         std::move(callback)));
      return;
    }

    DCHECK(base::SequencedTaskRunner::HasCurrentDefault());
    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(callback),
                       /*is_tpm_enabled=*/(state_ == State::kTpmTokenEnabled)));
  }

  bool InitializeNSSForChromeOSUser(const std::string& username_hash,
                                    const base::FilePath& path) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    if (chromeos_user_map_.find(username_hash) != chromeos_user_map_.end()) {
      // This user already exists in our mapping.
      DVLOG(2) << username_hash << " already initialized.";
      return false;
    }

    DVLOG(2) << "Opening NSS DB " << path.value();
    std::string db_name = base::StringPrintf("%s %s", kUserNSSDatabaseName,
                                             username_hash.c_str());
    ScopedPK11Slot public_slot(OpenPersistentNSSDBForPath(db_name, path));
    chromeos_user_map_[username_hash] =
        std::make_unique<ChromeOSUserData>(std::move(public_slot));
    return true;
  }

  bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());

    return !chromeos_user_map_[username_hash]
                ->private_slot_initialization_started();
  }

  void WillInitializeTPMForChromeOSUser(const std::string& username_hash) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());

    chromeos_user_map_[username_hash]
        ->set_private_slot_initialization_started();
  }

  void InitializeTPMForChromeOSUser(const std::string& username_hash,
                                    CK_SLOT_ID slot_id) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
    DCHECK(chromeos_user_map_[username_hash]
               ->private_slot_initialization_started());

    if (!chaps_module_)
      return;

    // Note that a reference is not taken to chaps_module_. This is safe since
    // ChromeOSTokenManager is Leaky, so the reference it holds is never
    // released.
    std::unique_ptr<TPMModuleAndSlot> tpm_args(
        new TPMModuleAndSlot(chaps_module_));
    TPMModuleAndSlot* tpm_args_ptr = tpm_args.get();
    base::ThreadPool::PostTaskAndReply(
        FROM_HERE,
        {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
        base::BindOnce(&ChromeOSTokenManager::InitializeTPMTokenInThreadPool,
                       slot_id, tpm_args_ptr),
        base::BindOnce(&ChromeOSTokenManager::OnInitializedTPMForChromeOSUser,
                       base::Unretained(this),  // ChromeOSTokenManager is leaky
                       username_hash, std::move(tpm_args)));
  }

  void OnInitializedTPMForChromeOSUser(
      const std::string& username_hash,
      std::unique_ptr<TPMModuleAndSlot> tpm_args) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DVLOG(2) << "Got tpm slot for " << username_hash << " "
             << !!tpm_args->tpm_slot;
    chromeos_user_map_[username_hash]->SetPrivateSlot(
        std::move(tpm_args->tpm_slot));
  }

  void InitializePrivateSoftwareSlotForChromeOSUser(
      const std::string& username_hash) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    VLOG(1) << "using software private slot for " << username_hash;
    DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());
    DCHECK(chromeos_user_map_[username_hash]
               ->private_slot_initialization_started());

    if (prepared_test_private_slot_) {
      chromeos_user_map_[username_hash]->SetPrivateSlot(
          std::move(prepared_test_private_slot_));
      return;
    }

    chromeos_user_map_[username_hash]->SetPrivateSlot(
        chromeos_user_map_[username_hash]->GetPublicSlot());
  }

  ScopedPK11Slot GetPublicSlotForChromeOSUser(
      const std::string& username_hash) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    if (username_hash.empty()) {
      DVLOG(2) << "empty username_hash";
      return ScopedPK11Slot();
    }

    if (chromeos_user_map_.find(username_hash) == chromeos_user_map_.end()) {
      LOG(ERROR) << username_hash << " not initialized.";
      return ScopedPK11Slot();
    }
    return chromeos_user_map_[username_hash]->GetPublicSlot();
  }

  ScopedPK11Slot GetPrivateSlotForChromeOSUser(
      const std::string& username_hash,
      base::OnceCallback<void(ScopedPK11Slot)> callback) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    if (username_hash.empty()) {
      DVLOG(2) << "empty username_hash";
      if (!callback.is_null()) {
        base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
            FROM_HERE, base::BindOnce(std::move(callback), ScopedPK11Slot()));
      }
      return ScopedPK11Slot();
    }

    DCHECK(chromeos_user_map_.find(username_hash) != chromeos_user_map_.end());

    return chromeos_user_map_[username_hash]->GetPrivateSlot(
        std::move(callback));
  }

  void CloseChromeOSUserForTesting(const std::string& username_hash) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    auto i = chromeos_user_map_.find(username_hash);
    DCHECK(i != chromeos_user_map_.end());
    chromeos_user_map_.erase(i);
  }

  void GetSystemNSSKeySlot(base::OnceCallback<void(ScopedPK11Slot)> callback) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    if (!IsInitializationFinished()) {
      // Call back to this method when initialization is finished.
      tpm_ready_callback_list_->AddUnsafe(
          base::BindOnce(&ChromeOSTokenManager::GetSystemNSSKeySlot,
                         base::Unretained(this) /* singleton is leaky */,
                         std::move(callback)));
      return;
    }

    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
        FROM_HERE,
        base::BindOnce(std::move(callback),
                       /*system_slot=*/ScopedPK11Slot(
                           system_slot_ ? PK11_ReferenceSlot(system_slot_.get())
                                        : nullptr)));
  }

  void ResetSystemSlotForTesting() { system_slot_.reset(); }

  void ResetTokenManagerForTesting() {
    // Prevent test failures when two tests in the same process use the same
    // ChromeOSTokenManager from different threads.
    DETACH_FROM_THREAD(thread_checker_);
    state_ = State::kInitializationNotStarted;

    // Configuring chaps_module_ here is not supported yet.
    CHECK(!chaps_module_);

    // Make sure there are no outstanding callbacks between tests.
    // OnceClosureList doesn't provide a way to clear the callback list.
    tpm_ready_callback_list_ = std::make_unique<base::OnceClosureList>();

    chromeos_user_map_.clear();
    ResetSystemSlotForTesting();  // IN-TEST
    prepared_test_private_slot_.reset();
  }

  void SetPrivateSoftwareSlotForChromeOSUserForTesting(ScopedPK11Slot slot) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    // Ensure that a previous value of prepared_test_private_slot_ is not
    // overwritten. Unsetting, i.e. setting a nullptr, however is allowed.
    DCHECK(!slot || !prepared_test_private_slot_);
    prepared_test_private_slot_ = std::move(slot);
  }

  bool IsInitializationStarted() {
    return (state_ != State::kInitializationNotStarted);
  }

 private:
  friend struct base::LazyInstanceTraitsBase<ChromeOSTokenManager>;

  ChromeOSTokenManager() { EnsureNSSInit(); }

  // NOTE(willchan): We don't actually cleanup on destruction since we leak NSS
  // to prevent non-joinable threads from using NSS after it's already been
  // shut down.
  ~ChromeOSTokenManager() = delete;

  bool IsInitializationFinished() {
    switch (state_) {
      case State::kTpmTokenEnabled:
      case State::kTpmTokenDisabled:
        return true;
      case State::kInitializationNotStarted:
      case State::kInitializationStarted:
      case State::kTpmTokenInitialized:
        return false;
    }
  }

  State state_ = State::kInitializationNotStarted;
  std::unique_ptr<base::OnceClosureList> tpm_ready_callback_list_ =
      std::make_unique<base::OnceClosureList>();

  raw_ptr<SECMODModule, ExperimentalAsh> chaps_module_ = nullptr;
  ScopedPK11Slot system_slot_;
  std::map<std::string, std::unique_ptr<ChromeOSUserData>> chromeos_user_map_;
  ScopedPK11Slot prepared_test_private_slot_;

  THREAD_CHECKER(thread_checker_);
};

base::LazyInstance<ChromeOSTokenManager>::Leaky g_token_manager =
    LAZY_INSTANCE_INITIALIZER;
}  // namespace

base::FilePath GetSoftwareNSSDBPath(
    const base::FilePath& profile_directory_path) {
  return profile_directory_path.AppendASCII(".pki").AppendASCII("nssdb");
}

void GetSystemNSSKeySlot(base::OnceCallback<void(ScopedPK11Slot)> callback) {
  g_token_manager.Get().GetSystemNSSKeySlot(std::move(callback));
}

void PrepareSystemSlotForTesting(ScopedPK11Slot slot) {
  DCHECK(!ChromeOSTokenManagerDataForTesting::GetInstance().test_system_slot);
  DCHECK(!g_token_manager.IsCreated() ||
         !g_token_manager.Get().IsInitializationStarted())
      << "PrepareSystemSlotForTesting is called after initialization started";

  ChromeOSTokenManagerDataForTesting::GetInstance().test_system_slot =
      std::move(slot);
}

void ResetSystemSlotForTesting() {
  if (g_token_manager.IsCreated()) {
    g_token_manager.Get().ResetSystemSlotForTesting();  // IN-TEST
  }
  ChromeOSTokenManagerDataForTesting::GetInstance().test_system_slot.reset();
}

void ResetTokenManagerForTesting() {
  if (g_token_manager.IsCreated()) {
    g_token_manager.Get().ResetTokenManagerForTesting();  // IN-TEST
  }
  ResetSystemSlotForTesting();  // IN-TEST
}

void IsTPMTokenEnabled(base::OnceCallback<void(bool)> callback) {
  g_token_manager.Get().IsTPMTokenEnabled(std::move(callback));
}

void InitializeTPMTokenAndSystemSlot(int token_slot_id,
                                     base::OnceCallback<void(bool)> callback) {
  g_token_manager.Get().InitializeTPMTokenAndSystemSlot(token_slot_id,
                                                        std::move(callback));
}

void FinishInitializingTPMTokenAndSystemSlot() {
  g_token_manager.Get().FinishInitializingTPMTokenAndSystemSlot();
}

bool InitializeNSSForChromeOSUser(const std::string& username_hash,
                                  const base::FilePath& path) {
  return g_token_manager.Get().InitializeNSSForChromeOSUser(username_hash,
                                                            path);
}

bool ShouldInitializeTPMForChromeOSUser(const std::string& username_hash) {
  return g_token_manager.Get().ShouldInitializeTPMForChromeOSUser(
      username_hash);
}

void WillInitializeTPMForChromeOSUser(const std::string& username_hash) {
  g_token_manager.Get().WillInitializeTPMForChromeOSUser(username_hash);
}

void InitializeTPMForChromeOSUser(const std::string& username_hash,
                                  CK_SLOT_ID slot_id) {
  g_token_manager.Get().InitializeTPMForChromeOSUser(username_hash, slot_id);
}

void InitializePrivateSoftwareSlotForChromeOSUser(
    const std::string& username_hash) {
  g_token_manager.Get().InitializePrivateSoftwareSlotForChromeOSUser(
      username_hash);
}

ScopedPK11Slot GetPublicSlotForChromeOSUser(const std::string& username_hash) {
  return g_token_manager.Get().GetPublicSlotForChromeOSUser(username_hash);
}

ScopedPK11Slot GetPrivateSlotForChromeOSUser(
    const std::string& username_hash,
    base::OnceCallback<void(ScopedPK11Slot)> callback) {
  return g_token_manager.Get().GetPrivateSlotForChromeOSUser(
      username_hash, std::move(callback));
}

void CloseChromeOSUserForTesting(const std::string& username_hash) {
  g_token_manager.Get().CloseChromeOSUserForTesting(username_hash);
}

void SetPrivateSoftwareSlotForChromeOSUserForTesting(ScopedPK11Slot slot) {
  g_token_manager.Get().SetPrivateSoftwareSlotForChromeOSUserForTesting(
      std::move(slot));
}

namespace {
void PrintDirectoryInfo(const base::FilePath& path) {
  base::stat_wrapper_t file_stat;

  if (base::File::Stat(path.value().c_str(), &file_stat) == -1) {
    base::File::Error error_code = base::File::OSErrorToFileError(errno);
    LOG(ERROR) << "Failed to collect directory info, error: " << error_code;
  }

  LOG(ERROR) << path << ", " << std::oct << file_stat.st_mode << std::dec
             << ", "
             << "uid " << file_stat.st_uid << ", "
             << "gid " << file_stat.st_gid << std::endl;
}
}  // namespace

// TODO(crbug.com/1163303): Remove when the bug is fixed.
void DiagnosePublicSlotAndCrash(const base::FilePath& nss_path) {
  LOG(ERROR) << "Public slot is invalid. Start collecting stats.";
  // Should be something like /home/chronos/u-<hash>/.pki/nssdb .
  LOG(ERROR) << "NSS path: " << nss_path;

  {
    // NSS files like pkcs11.txt, cert9.db, key4.db .
    base::FileEnumerator files(
        nss_path, /*recursive=*/false,
        /*file_type=*/base::FileEnumerator::FILES,
        /*pattern=*/base::FilePath::StringType(),
        base::FileEnumerator::FolderSearchPolicy::MATCH_ONLY,
        base::FileEnumerator::ErrorPolicy::STOP_ENUMERATION);
    LOG(ERROR) << "Public slot database files:";
    for (base::FilePath path = files.Next(); !path.empty();
         path = files.Next()) {
      base::FileEnumerator::FileInfo file_info = files.GetInfo();

      char buf[16];
      int read_result = base::ReadFile(path, buf, sizeof(buf) - 1);

      LOG(ERROR) << file_info.GetName() << ", " << std::oct
                 << file_info.stat().st_mode << std::dec << ", "
                 << "uid " << file_info.stat().st_uid << ", "
                 << "gid " << file_info.stat().st_gid << ", "
                 << file_info.stat().st_size << " bytes, "
                 << ((read_result > 0) ? "readable" : "not readable");
    }
    LOG(ERROR) << "Enumerate error code: " << files.GetError();
  }

  // NSS directory might not be created yet, also check parent directories.
  // Use u-hash directory as a comparison point for user and group ids and
  // access permissions.

  base::FilePath nssdb_path = nss_path.Append(base::FilePath::kParentDirectory);
  PrintDirectoryInfo(nssdb_path);

  base::FilePath pki_path = nssdb_path.Append(base::FilePath::kParentDirectory);
  PrintDirectoryInfo(pki_path);

  base::FilePath u_hash_path =
      pki_path.Append(base::FilePath::kParentDirectory);
  PrintDirectoryInfo(u_hash_path);

  {
    // Check whether the NSS path exists, and if not, check whether it's
    // possible to create it.
    if (base::DirectoryExists(nss_path)) {
      LOG(ERROR) << "NSS path exists (as expected).";
    } else {
      base::File::Error error = base::File::Error::FILE_OK;
      if (base::CreateDirectoryAndGetError(nss_path, &error)) {
        LOG(ERROR) << "NSS path didn't exist. Created successfully.";
      } else {
        LOG(ERROR) << "NSS path didn't exist. Failed to create, error: "
                   << error;
      }
    }
  }

  CHECK(false) << "Public slot is invalid.";
}

}  // namespace crypto
