// Copyright 2020 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/challenge_credentials/fido_utils.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/logging.h>
#include <brillo/secure_blob.h>

#include "cryptohome/cryptolib.h"
#include "cryptohome/fido.pb.h"

namespace cryptohome {

constexpr char kCrosLoginPrefix[] = "chromeos:login:";
constexpr char kIconUrl[] = "http://www.noicon.google.com";
// Default FIDO request timeout 30s.
constexpr base::TimeDelta kRequestTimeOut = base::TimeDelta::FromSeconds(30);

// MakeCredential only uses ES256 algorithms.
constexpr int kCOSEAlgorithmIdentifierES256 = -7;

std::vector<uint8_t> GetFidoUserId(const std::string& account_id) {
  auto digest =
      CryptoLib::Sha256ToSecureBlob(brillo::BlobFromString(account_id));
  return std::vector<uint8_t>(digest.begin(), digest.end());
}

std::unique_ptr<cryptohome::fido::PublicKeyCredentialRpEntity>
GetPublicKeyCredentialRpEntity(const std::string& id, const std::string& name) {
  auto rp = std::make_unique<cryptohome::fido::PublicKeyCredentialRpEntity>();
  rp->set_id(id);
  rp->set_name(name);
  return rp;
}

// Create User entity. Note the id is a 32-byte unique identifier derived from
// AccountIdentifier.account_id.
std::unique_ptr<cryptohome::fido::PublicKeyCredentialUserEntity>
GetPublicKeyCredentialUserEntity(const std::string& name,
                                 const std::vector<uint8_t>& id,
                                 const std::string& url_str,
                                 const std::string& display_name) {
  auto user =
      std::make_unique<cryptohome::fido::PublicKeyCredentialUserEntity>();
  user->set_name(name);
  user->set_id(std::string(id.begin(), id.end()));
  auto url = new cryptohome::fido::Url();
  url->set_url(url_str);
  user->set_allocated_icon(url);
  user->set_display_name(display_name);
  return user;
}

FidoPKCredCreationOptionsPtr BuildFidoMakeCredentialOptions(
    std::unique_ptr<cryptohome::fido::PublicKeyCredentialUserEntity> user,
    std::unique_ptr<cryptohome::fido::PublicKeyCredentialRpEntity> rp,
    std::vector<uint8_t> challenge,
    std::vector<cryptohome::fido::PublicKeyCredentialDescriptor>
        exclude_credentials,
    base::TimeDelta adjusted_timeout,
    std::unique_ptr<cryptohome::fido::CableRegistration>
        cable_registration_data,
    cryptohome::fido::ProtectionPolicy protection_policy,
    bool use_hmac_secret,
    bool enforce_protection_policy,
    std::string appid_exclude) {
  auto options =
      std::make_unique<cryptohome::fido::PublicKeyCredentialCreationOptions>();

  // Owned by |options| and lifecycle managed by |options|.
  options->set_allocated_relying_party(rp.release());
  options->set_allocated_user(user.release());
  auto param = options->add_public_key_parameters();
  param->set_type(cryptohome::fido::PUBLIC_KEY);
  param->set_algorithm_identifier(kCOSEAlgorithmIdentifierES256);

  options->set_adjusted_timeout(adjusted_timeout.InMilliseconds());
  options->set_challenge({challenge.begin(), challenge.end()});

  // TODO(xzhou): need to implement attestation signature checking.
  options->set_attestation(cryptohome::fido::NONE_ATTESTATION_PREFERENCE);

  // Specify the RP's authenticator attributes requirements.
  auto authenticator_selection =
      std::make_unique<cryptohome::fido::AuthenticatorSelectionCriteria>();

  authenticator_selection->set_authenticator_attachment(
      cryptohome::fido::NO_PREFERENCE /* equivalent to any or unset */);
  authenticator_selection->set_require_resident_key(false);
  // TODO(xzhou): If security key supports user verification, we may allow
  // security key as single factor authentication.
  authenticator_selection->set_user_verification(cryptohome::fido::DISCOURAGED);
  options->set_allocated_authenticator_selection(
      authenticator_selection.release());

  // A list of credentials RP knows about. If an authenticator has one of these
  // credentials, it should not create a new one.
  for (auto credential : exclude_credentials) {
    auto next = options->add_exclude_credentials();
    // Deep copy.
    next->CopyFrom(credential);
  }

  if (cable_registration_data) {
    options->set_allocated_cable_registration_data(
        cable_registration_data.release());
  }

  options->set_hmac_create_secret(use_hmac_secret);
  if (protection_policy != cryptohome::fido::ProtectionPolicy::UNSPECIFIED)
    options->set_protection_policy(protection_policy);
  options->set_enforce_protection_policy(enforce_protection_policy);

  if (!appid_exclude.empty()) {
    options->set_appid_exclude(appid_exclude);
  }
  return options;
}

FidoPKCredCreationOptionsPtr BuildFidoMakeCredentialOptions(
    const cryptohome::AccountIdentifier& account,
    const std::vector<uint8_t>& challenge,
    bool create_hmac_secret) {
  if (account.account_id() == "")
    return nullptr;

  std::vector<uint8_t> fido_account_id = GetFidoUserId(account.account_id());
  auto user = GetPublicKeyCredentialUserEntity(
      account.email(), /* name */
      fido_account_id, /* id */
      kIconUrl, account.email() /* display name */);

  auto rp = GetPublicKeyCredentialRpEntity(
      kCrosLoginPrefix + account.account_id(), /* the relying party id */
      "Chrome OS Login" /* relying party name */);

  return BuildFidoMakeCredentialOptions(
      std::move(user), std::move(rp), challenge, {}, /* exclude credentials */
      kRequestTimeOut, nullptr, /* cable registration data */
      cryptohome::fido::ProtectionPolicy::UNSPECIFIED, create_hmac_secret,
      false, /* enforce protection policy */
      "" /* appid exclude */);
}

FidoPKCredRequestOptionsPtr BuildFidoGetAssertionOptions(
    std::vector<uint8_t> challenge,
    int64_t adjusted_timeout,
    std::string relying_party_id,
    std::vector<cryptohome::fido::PublicKeyCredentialDescriptor>
        allow_credentials,
    std::string appid,
    std::vector<cryptohome::fido::CableAuthentication>
        cable_authentication_data) {
  auto options =
      std::make_unique<cryptohome::fido::PublicKeyCredentialRequestOptions>();
  std::string str_challenge(challenge.begin(), challenge.end());
  options->set_challenge(str_challenge);
  options->set_adjusted_timeout(adjusted_timeout);
  options->set_relying_party_id(relying_party_id);

  for (auto& credential : allow_credentials) {
    auto next = options->add_allow_credentials();
    next->CopyFrom(credential);
  }

  options->set_appid(appid);
  for (const auto& cable_authentication : cable_authentication_data) {
    auto next = options->add_cable_authentication_data();
    next->CopyFrom(cable_authentication);
  }
  return options;
}

FidoPKCredRequestOptionsPtr BuildFidoGetAssertionOptions(
    std::vector<uint8_t> challenge,
    std::string relying_party_id,
    std::string appid) {
  return BuildFidoGetAssertionOptions(
      challenge, kRequestTimeOut.InMilliseconds(), relying_party_id,
      {}, /* allow credentials */
      appid, {} /* Cloud Assisted BLE authentication data */);
}

}  // namespace cryptohome
