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

#include "cryptohome/install_attributes.h"

#include <sys/types.h>

#include <limits>
#include <string>

#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/time/time.h>

#include "cryptohome/lockbox.h"
#include "cryptohome/tpm_init.h"

#include "install_attributes.pb.h"  // NOLINT(build/include)

using base::FilePath;

namespace cryptohome {

// By default, we store this with other cryptohome state.
const FilePath::CharType InstallAttributes::kDefaultDataFile[] =
  "/home/.shadow/install_attributes.pb";
const mode_t InstallAttributes::kDataFilePermissions = 0644;
// This is the default location for the cache file.
const FilePath::CharType InstallAttributes::kDefaultCacheFile[] =
  "/run/lockbox/install_attributes.pb";
const mode_t InstallAttributes::kCacheFilePermissions = 0644;

InstallAttributes::InstallAttributes(Tpm* tpm)
  : is_first_install_(false),
    is_invalid_(false),
    is_initialized_(false),
    data_file_(kDefaultDataFile),
    cache_file_(kDefaultCacheFile),
    default_attributes_(new SerializedInstallAttributes()),
    default_lockbox_(new Lockbox(tpm, Tpm::kLockboxIndex)),
    default_platform_(new Platform()),
    attributes_(default_attributes_.get()),
    lockbox_(default_lockbox_.get()),
    platform_(default_platform_.get()) {
  SetTpm(tpm);  // make sure to check TPM status if needed.
  version_ = attributes_->version();  // versioning controlled by pb default.
}

InstallAttributes::~InstallAttributes() {
}

bool InstallAttributes::PrepareSystem() {
  set_is_first_install(true);
  Lockbox::ErrorId error_id;
  // Delete the attributes file if it exists.
  if (platform_->FileExists(data_file_) &&
      !platform_->DeleteFile(data_file_, false)) {
    LOG(ERROR) << "PrepareSystem() unable to delete old data!";
    return false;
  }
  // If a TPM is in use, let's clean up the lockbox.
  if (is_secure())
    return lockbox()->Destroy(&error_id);
  return true;
}

void InstallAttributes::SetIsInvalid(bool is_invalid) {
  // If a store is invalid, make sure it is forced to be empty.
  is_invalid_ = is_invalid;
  if (is_invalid) {
    set_is_first_install(false);
    attributes_->Clear();
  }
}

void InstallAttributes::SetTpm(Tpm* tpm) {
  // Technically, it is safe to call SetTpm, then Init() again, but it could
  // also cause weirdness and report that data is TPM-backed when it isn't.
  DCHECK(!is_initialized()) << "SetTpm used after a successful Init().";
  if (tpm && !tpm->IsEnabled()) {
    LOG(WARNING) << "set_tpm() missing or disabled TPM provided.";
    tpm = NULL;  // Don't give it to Lockbox.
  }
  set_is_secure(tpm != NULL);
  lockbox_->set_tpm(tpm);
}

bool InstallAttributes::Init(TpmInit* tpm_init) {
  Lockbox::ErrorId error_id;

  // Insure that if Init() was called and it failed, we can retry cleanly.
  attributes_->Clear();
  SetIsInvalid(false);
  set_is_initialized(false);

  if (is_first_install()) {
    if (!is_secure()) {
      LOG(WARNING) << "InstallAttributes are insecure without a TPM.";
      set_is_initialized(true);
      return true;
    }
    if (!lockbox()->Create(&error_id)) {
      if (error_id == Lockbox::kErrorIdInsufficientAuthorization)
        LOG(ERROR) << "First install, but no TPM credentials provided.";
      SetIsInvalid(true);
      return false;
    }

    set_is_initialized(true);
    tpm_init->RemoveTpmOwnerDependency(
        Tpm::TpmOwnerDependency::kInstallAttributes);
    return true;
  }

  if (is_secure() && !lockbox()->Load(&error_id)) {
    // There are two non-terminal error cases:
    // 1. No NVRAM space is defined.  This will occur on systems that
    //    are autoupdated with this code but never went through the OOBE,
    //    or if creation was interrupted after TPM Ownership happened.
    // 2. NVRAM space exists and is unlocked. It means the system was powered
    //    off before any data was stored.
    switch (error_id) {
    case Lockbox::kErrorIdNoNvramSpace:
      LOG(INFO) << "Resuming interrupted InstallAttributes. (Create needed.)";
      if (!lockbox()->Create(&error_id)) {
        if (error_id == Lockbox::kErrorIdInsufficientAuthorization)
          DLOG(INFO) << "Legacy install. (Can never create NVRAM space.)";
        else
          LOG(ERROR) << "Create failed, Lockbox error: " << error_id;
      } else {
        // Create worked, so act like the kErrorIdNoNvramData path now.
        set_is_first_install(true);
      }
      set_is_initialized(true);
      // No data.
      return true;
      break;
    case Lockbox::kErrorIdNoNvramData:
      LOG(INFO) << "Resuming interrupted InstallAttributes. (Store needed.)";
      set_is_first_install(true);
      set_is_initialized(true);
      // Since we write when we finalize, we don't try to reparse.
      return true;
      break;
    default:
      LOG(ERROR) << "InstallAttributes failed to initialize.";
      SetIsInvalid(true);
      return false;
    }
  }

  // Load the file from disk.
  brillo::Blob blob;
  if (!platform_->ReadFile(data_file_, &blob)) {
    LOG(WARNING) << "Init() failed to read attributes file.";
    // If this is an insecure install, then we can just start the
    // file fresh, otherwise it signifies tampering.
    if (is_secure()) {
      SetIsInvalid(true);
      return false;
    }
    LOG(INFO) << "Init() assuming first-time install for TPM-less system.";
    set_is_first_install(true);
    set_is_initialized(true);
    return true;
  }

  // Prior to attempting to deserialize the data, ensure it has not
  // been tampered with.
  if (is_secure() && !lockbox()->Verify(blob, &error_id)) {
    LOG(ERROR) << "Init() could not verify attribute data!";
    SetIsInvalid(true);
    return false;
  }

  if (!attributes_->ParseFromArray(
         static_cast<google::protobuf::uint8*>(blob.data()),
         blob.size())) {
    LOG(ERROR) << "Failed to parse data file (" << blob.size() << " bytes)";
    SetIsInvalid(true);
    return false;
  }

  set_is_initialized(true);
  return true;
}

int InstallAttributes::FindIndexByName(const std::string& name) const {
  std::string name_str(name);
  for (int i = 0; i < attributes_->attributes_size(); ++i) {
    if (attributes_->attributes(i).name().compare(name_str) == 0)
      return i;
  }
  return -1;
}

bool InstallAttributes::Get(const std::string& name,
                            brillo::Blob* value) const {
  int index = FindIndexByName(name);
  if (index == -1)
    return false;
  return GetByIndex(index, NULL, value);
}

bool InstallAttributes::GetByIndex(int index,
                                   std::string* name,
                                   brillo::Blob* value) const {
  if (index < 0 || index >= attributes_->attributes_size()) {
    LOG(ERROR) << "GetByIndex called with invalid index.";
    return false;
  }
  const SerializedInstallAttributes::Attribute* const attr =
    &attributes_->attributes(index);
  if (name) {
    name->assign(attr->name());
  }
  if (value) {
    value->resize(attr->value().length());
    memcpy(&value->at(0), attr->value().c_str(), value->size());
  }
  return true;
}

bool InstallAttributes::Set(const std::string& name,
                            const brillo::Blob& value) {
  if (!is_first_install()) {
    LOG(ERROR) << "Set() called on immutable attributes.";
    return false;
  }

  if (Count() == std::numeric_limits<int>::max()) {
    LOG(ERROR) << "Set() cannot insert into full attribute store.";
    return false;
  }

  // Clobber an existing entry if it exists.
  int index = FindIndexByName(name);
  if (index != -1) {
    SerializedInstallAttributes::Attribute* attr =
      attributes_->mutable_attributes(index);
    attr->set_value(std::string(reinterpret_cast<const char*>(value.data()),
                                value.size()));
    return true;
  }

  SerializedInstallAttributes::Attribute* attr = attributes_->add_attributes();
  if (!attr) {
    LOG(ERROR) << "Failed to add a new attribute.";
    return false;
  }
  attr->set_name(name);
  attr->set_value(std::string(reinterpret_cast<const char*>(value.data()),
                              value.size()));
  return true;
}

bool InstallAttributes::Finalize() {
  if (!IsReady()) {
    LOG(ERROR) << "Finalize() called with invalid/uninitialized data.";
    return false;
  }
  // Repeated calls to Finalize() are idempotent.
  if (!is_first_install())
    return true;

  // Restamp the version.
  attributes_->set_version(version_);

  // Serialize the bytestream
  brillo::Blob attr_bytes;
  if (!SerializeAttributes(&attr_bytes)) {
    LOG(ERROR) << "Finalize() failed to serialize the attributes.";
    return false;
  }

  Lockbox::ErrorId error;
  DLOG(INFO) << "Finalizing() " << attr_bytes.size() << " bytes.";
  if (is_secure() && !lockbox()->Store(attr_bytes, &error)) {
    LOG(ERROR) << "Finalize() failed with Lockbox error: " << error;
    // It may be possible to recover from a failed NVRAM store. So the
    // instance is not marked invalid.
    return false;
  }

  if (!platform_->WriteFileAtomicDurable(data_file_, attr_bytes,
                                         kDataFilePermissions)) {
    LOG(ERROR) << "Finalize() write failed after locking the Lockbox.";
    SetIsInvalid(true);
    return false;
  }

  // As the cache file is stored on tmpfs, durable write is not required but we
  // need atomicity to be safe in case of concurrent reads.
  if (!platform_->WriteFileAtomic(cache_file_, attr_bytes,
                                  kCacheFilePermissions)) {
    LOG(WARNING) << "Finalize() failed to create cache file.";
  }

  LOG(INFO) << "InstallAttributes have been finalized.";
  set_is_first_install(false);
  NotifyFinalized();
  return true;
}

int InstallAttributes::Count() const {
  return attributes_->attributes_size();
}

bool InstallAttributes::SerializeAttributes(brillo::Blob* out_bytes) {
  out_bytes->resize(attributes_->ByteSize());
  attributes_->SerializeWithCachedSizesToArray(
    static_cast<google::protobuf::uint8*>(out_bytes->data()));
  return true;
}

base::Value* InstallAttributes::GetStatus() {
  base::DictionaryValue* dv = new base::DictionaryValue();
  dv->SetBoolean("initialized", is_initialized());
  dv->SetInteger("version", version());
  dv->SetInteger("lockbox_index", lockbox()->nvram_index());
  dv->SetInteger("lockbox_nvram_version", lockbox()->nvram_version());
  dv->SetBoolean("secure", is_secure());
  dv->SetBoolean("invalid", is_invalid());
  dv->SetBoolean("first_install", is_first_install());
  dv->SetInteger("size", Count());
  if (Count()) {
    base::DictionaryValue* attrs = new base::DictionaryValue();
    std::string key;
    brillo::Blob value;
    for (int i = 0; i < Count(); i++) {
      GetByIndex(i, &key, &value);
      std::string value_str(reinterpret_cast<const char*>(value.data()));
      attrs->SetString(key, value_str);
    }
    dv->Set("attrs", attrs);
  }
  return dv;
}

}  // namespace cryptohome
