// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Contains the implementation of class Pkcs11Init.

#include "pkcs11_init.h"

#include <iostream>

#include <base/logging.h>
#include <base/string_util.h>
#include <glib.h>
#include <opencryptoki/pkcs11.h>

#include "platform.h"


namespace cryptohome {

// static
const CK_SLOT_ID Pkcs11Init::kDefaultTpmSlotId = 0;
const CK_ULONG Pkcs11Init::kMaxPinLen = 9;
const CK_ULONG Pkcs11Init::kMaxLabelLen = 32;
// openCryptoki 2.2.4 PIN defaults as per the README at:
// http://opencryptoki.git.sourceforge.net/git/gitweb.cgi?p=opencryptoki
//       /opencryptoki;a=summary
const CK_CHAR Pkcs11Init::kDefaultOpencryptokiSoPin[] = "87654321";
const CK_CHAR Pkcs11Init::kDefaultOpencryptokiUserPin[] = "12345678";
const CK_CHAR Pkcs11Init::kDefaultSoPin[] = "000000";
const CK_CHAR Pkcs11Init::kDefaultUserPin[] = "111111";
const CK_CHAR Pkcs11Init::kDefaultLabel[] = "User-Specific TPM Token";
const char Pkcs11Init::kOpencryptokiDir[] = "/var/lib/opencryptoki";
const char Pkcs11Init::kUserTokenLink[] = "/var/lib/opencryptoki/tpm/chronos";
const char Pkcs11Init::kRootTokenLink[] = "/var/lib/opencryptoki/tpm/root";
const char Pkcs11Init::kUserTokenDir[] = "/home/chronos/user/.tpm";
const char Pkcs11Init::kRootTokenDir[] = "./chronos";
const char Pkcs11Init::kPkcs11Group[] = "pkcs11";
const char Pkcs11Init::kOldTokenEntry[] =
    "/var/lib/opencryptoki/pk_config_data";
const std::string Pkcs11Init::kPkcs11StartupPath = "/usr/sbin/pkcs11_startup";
const std::string Pkcs11Init::kPkcsSlotdPath = "/usr/sbin/pkcsslotd";
const std::string Pkcs11Init::kPkcsSlotPath = "/usr/sbin/pkcs_slot";
const std::string Pkcs11Init::kPkcsSlotCmd[] = { Pkcs11Init::kPkcsSlotPath,
                                                 "0", "tpm" };
// This file in the user's cryptohome signifies that Pkcs11 initialization
// was completed for the user.
const std::string Pkcs11Init::kPkcs11InitializedFile =
    "/home/chronos/user/.tpm/.isinitialized";

extern const char* kTpmOwnedFile;
extern const std::string kDefaultSharedUser;

// Helper function to copy a CK_CHAR string |src| to another CK_CHAR string
// |dest| with at most most |len-1| characters. |dest| is then null-terminated.
void CKCharcpy(CK_CHAR* dest, const CK_CHAR* src, CK_ULONG len) {
  strncpy(reinterpret_cast<char*>(dest),
          reinterpret_cast<const char*>(src),
          len - 1);
  dest[len - 1] = '\0';
}


void Pkcs11Init::GetTpmTokenInfo(gchar **OUT_label,
                                 gchar **OUT_user_pin) {
  *OUT_label = g_strdup(reinterpret_cast<const gchar *>(kDefaultLabel));
  *OUT_user_pin = g_strdup(reinterpret_cast<const gchar *>(kDefaultUserPin));
}

bool Pkcs11Init::Initialize() {
  Platform platform;
  // Determine required uid and gids.
  if (!platform.GetGroupId(kPkcs11Group, &pkcs11_group_id_)) {
    LOG(ERROR) << "Couldn't get the group ID for group " << kPkcs11Group;
    return false;
  }
  if (!platform.GetUserId(kDefaultSharedUser, &chronos_user_id_,
                          &chronos_group_id_)) {
    LOG(ERROR) << "Couldn't get the user/group ID for user "
               << kDefaultSharedUser;
    return false;
  }

  if (!SetUpPkcs11System())
    return false;

  if (IsTokenBroken()) {
    LOG(INFO) << "Broken or uninitialized token. Removing user token dir "
              << kUserTokenDir << " just to be safe.";
    RemoveUserTokenDir();
    if (!SetUpLinksAndPermissions())
      return false;
    return SetUpTPMToken();
  }
  LOG(INFO) << "PKCS#11 is already initialized.";
  return true;
}

bool Pkcs11Init::SetUpPkcs11System() {
  Platform platform;
  // Run the pkcs11_startup script that will detect available tokens and update
  // pk_config_data appropriately. This is used later by pkcsslotd.
  std::string startup_cmd = kPkcs11StartupPath;
  std::string startup_args[1] = { startup_cmd };
  std::vector<std::string> startup_arguments;
  startup_arguments.assign(startup_args,
                           startup_args + arraysize(startup_args));
  // TODO(gauravsh): Consider moving to using process functions from
  // src/common/chromeos/process.h instead.
  //
  // Note: This must be run as root so that it can create the necessary
  // directories with the correct permissions under /var/lib. Since it's a
  // and not a service daemon, we are OK with that.
  if (!platform.Exec(startup_cmd, startup_arguments,
                     static_cast<uid_t>(0),  // Run as root.
                     pkcs11_group_id_))
    return false;

  // Start the slot manager daemon (pkcsslotd).
  std::string slotd_cmd = kPkcsSlotdPath;
  std::string slotd_args[1] = { slotd_cmd };
  std::vector<std::string> slotd_arguments;
  slotd_arguments.assign(slotd_args, slotd_args + arraysize(slotd_args));
  // TODO(gauravsh): Figure out if pkcsslotd can be run as a different primary
  // uid.
  if (!platform.Exec(slotd_cmd, slotd_arguments, chronos_user_id_,
                     pkcs11_group_id_))
    return false;
  return true;
}

bool Pkcs11Init::SetUpTPMToken() {
  Platform platform;

  // Setup the TPM as a token.
  std::vector<std::string> arguments;
  arguments.assign(kPkcsSlotCmd, kPkcsSlotCmd + arraysize(kPkcsSlotCmd));
  if (!platform.Exec(kPkcsSlotPath, arguments, chronos_user_id_,
                     pkcs11_group_id_)) {
    LOG(ERROR) << "Couldn't configure the tpm as a token. "
               << kPkcsSlotPath << " " << kPkcsSlotCmd[1] << " "
               << kPkcsSlotCmd[2] << "failed.";
    return false;
  }

  CK_RV rv = C_Initialize(NULL);
  if (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED && rv != CKR_OK) {
    LOG(ERROR) << "C_Initialize returned error code 0x" << std::hex << rv;
    return false;
  }

  CK_SLOT_ID slot_id = kDefaultTpmSlotId;

  // Initialize the token by login using the default openCryptoki SO PIN.
  CK_CHAR old_pin[kMaxPinLen];
  CK_CHAR ck_label[kMaxLabelLen];
  CKCharcpy(old_pin, kDefaultOpencryptokiSoPin, sizeof(old_pin));
  CKCharcpy(ck_label, kDefaultLabel, sizeof(ck_label));

  LOG(INFO) << "Initializing token by using default openCryptoki SO PIN.";
  rv = C_InitToken(slot_id,
                   old_pin, strlen(reinterpret_cast<const char*>(old_pin)),
                   ck_label);
  if (rv != CKR_OK) {
    LOG(ERROR) << "C_InitToken returned error code 0x" << std::hex << rv;
    return false;
  }

  // Reset the SO PIN to our default value.
  CK_CHAR new_pin[kMaxPinLen];
  CKCharcpy(new_pin, kDefaultSoPin, sizeof(new_pin));
  LOG(INFO) << "Resetting the SO PIN on the token to our default value.";
  if (!SetPin(slot_id, CKU_SO,
              old_pin, strlen(reinterpret_cast<const char*>(old_pin)),
              new_pin, strlen(reinterpret_cast<const char*>(new_pin)))) {
    LOG(ERROR) << "Couldn't reset the SO PIN on the token.";
    return false;
  }

  // Reset the User PIN to our default value.
  CKCharcpy(old_pin, kDefaultOpencryptokiUserPin, sizeof(old_pin));
  CKCharcpy(new_pin, kDefaultUserPin, sizeof(new_pin));
  LOG(INFO) << "Resetting the User PIN on the token to our default value.";
  if (!SetPin(slot_id, CKU_USER,
              old_pin, strlen(reinterpret_cast<const char*>(old_pin)),
              new_pin, strlen(reinterpret_cast<const char*>(new_pin)))) {
    LOG(ERROR) << "Couldn't reset the User PIN on the token.";
    return false;
  }

  LOG(INFO) << "Token initialization complete.";
  return SetInitialized(true);
}

bool Pkcs11Init::SetUpLinksAndPermissions() {
  Platform platform;
  std::string opencryptoki_tpm = StringPrintf("%s/tpm", kOpencryptokiDir);
  if (!platform.CreateDirectory(opencryptoki_tpm)) {
    LOG(ERROR) << "Couldn't create openCryptoki token directory "
               << opencryptoki_tpm;
    return false;
  }

  // Ensure symbolic links for the token directories are correctly setup.
  // TODO(gauravsh): (crosbug.com/7284) Patch openCryptoki so that this is no
  // longer necessary.
  if (!platform.Symlink(std::string(kUserTokenDir),
                        std::string(kUserTokenLink)))
    return false;

  if (!platform.Symlink(std::string(kRootTokenDir),
                        std::string(kRootTokenLink)))
    return false;

  // Remove old token directory.
  if (platform.DirectoryExists(kOldTokenEntry) &&
      !platform.DeleteFile(kOldTokenEntry, true))
    return false;

  // Create token directory, since initialization neither creates or populates
  // it.
  std::string token_obj_dir = StringPrintf("%s/TOK_OBJ", kUserTokenDir);
  if (!platform.DirectoryExists(token_obj_dir) &&
      !platform.CreateDirectory(token_obj_dir))
    return false;

  // Set correct permissions on opencryptoki directory (root:$PKCS11_GROUP_ID).
  if (!platform.SetOwnershipRecursive(std::string(kOpencryptokiDir),
                                      static_cast<uid_t>(0),  // Root uid is 0.
                                      pkcs11_group_id_)) {
    LOG(ERROR) << "Couldn't set file ownership for " << kOpencryptokiDir;
    return false;
  }

  // Setup permissions on the user token directory to ensure that users can
  // access their own data.
  if (!platform.SetOwnershipRecursive(std::string(kUserTokenDir),
                                      chronos_user_id_,
                                      pkcs11_group_id_)) {
    LOG(ERROR) << "Couldn't set file ownership for " << kOpencryptokiDir;
    return false;
  }

  return true;
}

bool Pkcs11Init::IsTokenBroken() {
  Platform platform;
  // A non-existent token is also broken.
  if (!platform.FileExists(StringPrintf("%s/NVTOK.DAT", kUserTokenDir)))
    return true;

  if (!platform.FileExists(kTpmOwnedFile)) {
    LOG(WARNING) << "TPM is not owned, token can't valid.";
    return true;
  }

  if (!platform.FileExists(StringPrintf("%s/PRIVATE_ROOT_KEY.pem",
                                        kUserTokenDir)) ||
      !platform.FileExists(StringPrintf("%s/TOK_OBJ/70000000",
                                        kUserTokenDir))) {
    LOG(WARNING) << "PKCS#11 token is missing some files. Possibly not yet "
                 << "initialized? TOK_OBJ contents were: ";
    // Log the contents of what was observed in exists in the TOK_OBJ directory.
    std::vector<std::string> tok_file_list;
    platform.EnumerateFiles(StringPrintf("%s/TOK_OBJ/",  kUserTokenDir), true,
                            &tok_file_list);
    for (std::vector<std::string>::iterator it = tok_file_list.begin();
         it != tok_file_list.end(); ++it)
      LOG(WARNING) << *it;
    return true;
  }

  // At this point, we are done with basic sanity checking.
  // Now check if our "it is initialized" special file is still there.
  if (!platform.FileExists(kPkcs11InitializedFile))
    return true;

  LOG(INFO) << "PKCS#11 token looks ok.";
  return false;
}

bool Pkcs11Init::RemoveUserTokenDir() {
  Platform platform;
  if (platform.DirectoryExists(kUserTokenDir)) {
    return platform.DeleteFile(kUserTokenDir, true);
  }
  return true;
}

bool Pkcs11Init::SetInitialized(bool status) {
  Platform platform;
  if (!status) {
    // Remove initialization state.
    platform.DeleteFile(kPkcs11InitializedFile, false);
    is_initialized_ = false;
    return true;
  }

  chromeos::Blob empty_blob;
  if (!platform.WriteFile(kPkcs11InitializedFile, empty_blob))
    return false;
  is_initialized_ = true;
  return true;
}

bool Pkcs11Init::SetPin(CK_SLOT_ID slot_id, CK_USER_TYPE user,
                        CK_CHAR_PTR old_pin, CK_ULONG old_pin_len,
                        CK_CHAR_PTR new_pin, CK_ULONG new_pin_len) {
  CK_RV rv;
  CK_SESSION_HANDLE session_handle = 0;
  rv = C_OpenSession(slot_id, CKF_RW_SESSION | CKF_SERIAL_SESSION,
                     NULL, NULL,
                     &session_handle);
  if (rv != CKR_OK) {
    LOG(ERROR) << "C_OpenSession returned error code 0x" << std::hex << rv;
    return false;
  }

  rv = C_Login(session_handle, user, old_pin, old_pin_len);
  if (rv != CKR_OK) {
    LOG(ERROR) << "Couldn't login using the old pin.";
    LOG(ERROR) << "C_Login returned error code 0x" << std::hex << rv;
    return false;
  }

  rv = C_SetPIN(session_handle, old_pin, old_pin_len, new_pin, new_pin_len);
  if (rv != CKR_OK) {
    C_CloseAllSessions(slot_id);
    LOG(ERROR) << "C_SetPIN returned error code 0x" << std::hex << rv;
    return false;
  }

  rv = C_CloseAllSessions(slot_id);
  if (rv != CKR_OK) {
    LOG(ERROR) << "C_CloseAllSessions returned error code 0x" << std::hex << rv;
    return false;
  }

  return true;
}


}  // namespace cryptohome
