// 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 "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/bind.h"
#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/lazy_instance.h"
#include "base/location.h"
#include "base/logging.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/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_checker.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.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) {}

    SECMODModule* 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
    base::ThreadRestrictions::ScopedAllowIO allow_io;

    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::SequencedTaskRunnerHandle::IsSet());
    base::SequencedTaskRunnerHandle::Get()->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::ThreadTaskRunnerHandle::Get()->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::SequencedTaskRunnerHandle::Get()->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>();

  SECMODModule* 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(std::stringstream& ss, const base::FilePath& path) {
  base::stat_wrapper_t file_stat;
  base::File::Error error_code = base::File::Error::FILE_OK;
  if (base::File::Stat(path.value().c_str(), &file_stat) == -1) {
    error_code = base::File::OSErrorToFileError(errno);
  }
  ss << path << ", ";
  ss << std::oct << file_stat.st_mode << std::dec << ", ";
  ss << "uid " << file_stat.st_uid << ", ";
  ss << "gid " << file_stat.st_gid << std::endl;

  ss << "Enumerate error code: " << error_code << std::endl;
}
}  // namespace

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

  {
    // 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);
    ss << "Public slot database files:" << std::endl;
    for (base::FilePath path = files.Next(); !path.empty();
         path = files.Next()) {
      base::FileEnumerator::FileInfo file_info = files.GetInfo();
      ss << file_info.GetName() << ", ";
      ss << std::oct << file_info.stat().st_mode << std::dec << ", ";
      ss << "uid " << file_info.stat().st_uid << ", ";
      ss << "gid " << file_info.stat().st_gid << ", ";
      ss << file_info.stat().st_size << " bytes, ";

      char buf[16];
      int read_result = base::ReadFile(path, buf, sizeof(buf) - 1);
      ss << ((read_result > 0) ? "readable" : "not readable");

      ss << std::endl;
    }
    ss << "Enumerate error code: " << files.GetError() << std::endl;
  }

  // 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(ss, nssdb_path);

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

  base::FilePath u_hash_path =
      pki_path.Append(base::FilePath::kParentDirectory);
  PrintDirectoryInfo(ss, 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)) {
      ss << "NSS path exists." << std::endl;
    } else {
      base::File::Error error = base::File::Error::FILE_OK;
      if (base::CreateDirectoryAndGetError(nss_path, &error)) {
        ss << "NSS path didn't exist. Created successfully." << std::endl;
      } else {
        ss << "NSS path didn't exist. Failed to create, error: " << error
           << std::endl;
      }
    }
  }

  CHECK(false) << ss.str();
}

}  // namespace crypto
