// 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/fido/attested_credential_data.h"

#include <algorithm>
#include <string>
#include <utility>

#include <base/numerics/safe_math.h>
#include <base/strings/string_number_conversions.h>
#include <chromeos/cbor/reader.h>

#include "cryptohome/fido/ec_public_key.h"
#include "cryptohome/fido/fido_constants.h"
#include "cryptohome/fido/fido_parsing_utils.h"
#include "cryptohome/fido/public_key.h"
#include "cryptohome/fido/utils.h"

namespace cryptohome {
namespace fido_device {

// static
base::Optional<std::pair<AttestedCredentialData, base::span<const uint8_t>>>
AttestedCredentialData::ConsumeFromCtapResponse(
    base::span<const uint8_t> buffer) {
  if (buffer.size() < kAaguidLength)
    return base::nullopt;

  auto aaguid = buffer.first<kAaguidLength>();
  buffer = buffer.subspan(kAaguidLength);

  if (buffer.size() < kCredentialIdLengthLength)
    return base::nullopt;

  auto credential_id_length_span = buffer.first<kCredentialIdLengthLength>();
  const size_t credential_id_length =
      (base::strict_cast<size_t>(credential_id_length_span[0]) << 8) |
      base::strict_cast<size_t>(credential_id_length_span[1]);
  buffer = buffer.subspan(kCredentialIdLengthLength);

  if (buffer.size() < credential_id_length)
    return base::nullopt;

  auto credential_id = buffer.first(credential_id_length);
  buffer = buffer.subspan(credential_id_length);

  // The public key is a CBOR map and is thus variable length. Therefore the
  // CBOR parser needs to be invoked to find its length, even though the result
  // is discarded.
  size_t bytes_read;
  if (!cbor::Reader::Read(buffer, &bytes_read)) {
    return base::nullopt;
  }

  // Only EC Public key is supported for now.
  auto credential_public_key =
      ECPublicKey::ParseECPublicKey(buffer.first(bytes_read));
  if (!credential_public_key)
    return base::nullopt;

  buffer = buffer.subspan(bytes_read);
  return std::make_pair(
      AttestedCredentialData(aaguid, credential_id_length_span,
                             fido_parsing_utils::Materialize(credential_id),
                             std::move(credential_public_key)),
      buffer);
}

// static
base::Optional<AttestedCredentialData>
AttestedCredentialData::CreateFromU2fRegisterResponse(
    base::span<const uint8_t> u2f_data, std::unique_ptr<PublicKey> public_key) {
  // TODO(crbug/799075): Introduce a CredentialID class to do this extraction.
  // Extract the length of the credential (i.e. of the U2FResponse key
  // handle). Length is big endian.
  std::vector<uint8_t> extracted_length =
      fido_parsing_utils::Extract(u2f_data, kU2fKeyHandleLengthOffset, 1);

  if (extracted_length.empty()) {
    return base::nullopt;
  }

  // For U2F register request, device AAGUID is set to zeros.
  std::array<uint8_t, kAaguidLength> aaguid = {};

  // Note that U2F responses only use one byte for length.
  std::array<uint8_t, kCredentialIdLengthLength> credential_id_length = {
      0, extracted_length[0]};

  // Extract the credential id (i.e. key handle).
  std::vector<uint8_t> credential_id = fido_parsing_utils::Extract(
      u2f_data, kU2fKeyHandleOffset,
      base::strict_cast<size_t>(credential_id_length[1]));

  if (credential_id.empty()) {
    return base::nullopt;
  }

  return AttestedCredentialData(aaguid, credential_id_length,
                                std::move(credential_id),
                                std::move(public_key));
}

AttestedCredentialData::AttestedCredentialData(AttestedCredentialData&& other) =
    default;

AttestedCredentialData& AttestedCredentialData::operator=(
    AttestedCredentialData&& other) = default;

AttestedCredentialData::~AttestedCredentialData() = default;

bool AttestedCredentialData::IsAaguidZero() const {
  return std::all_of(aaguid_.begin(), aaguid_.end(),
                     [](uint8_t v) { return v == 0; });
}

void AttestedCredentialData::DeleteAaguid() {
  std::fill(aaguid_.begin(), aaguid_.end(), 0);
}

std::vector<uint8_t> AttestedCredentialData::SerializeAsBytes() const {
  std::vector<uint8_t> attestation_data;
  fido_parsing_utils::Append(&attestation_data, aaguid_);
  fido_parsing_utils::Append(&attestation_data, credential_id_length_);
  fido_parsing_utils::Append(&attestation_data, credential_id_);
  fido_parsing_utils::Append(&attestation_data, public_key_->EncodeAsCOSEKey());
  return attestation_data;
}

const PublicKey* AttestedCredentialData::GetPublicKey() const {
  return public_key_.get();
}

uint16_t AttestedCredentialData::GetCredentialIdLength() {
  uint16_t length;
  fido::ReadBigEndian<uint16_t>(
      reinterpret_cast<const char*>(&credential_id_length_[0]), &length);
  return length;
}

std::string AttestedCredentialData::ToString() {
  std::stringstream ss;
  ss << "attested data: {"
     << "aaguid: " << base::HexEncode(aaguid_.data(), aaguid_.size()) << ", "
     << "credential length: " << GetCredentialIdLength() << ", "
     << "credential id: "
     << base::HexEncode(credential_id_.data(), credential_id_.size()) << ", "
     << "credential: " << public_key_->ToString();
  return ss.str();
}

AttestedCredentialData::AttestedCredentialData(
    base::span<const uint8_t, kAaguidLength> aaguid,
    base::span<const uint8_t, kCredentialIdLengthLength> credential_id_length,
    std::vector<uint8_t> credential_id,
    std::unique_ptr<PublicKey> public_key)
    : aaguid_(fido_parsing_utils::Materialize(aaguid)),
      credential_id_length_(
          fido_parsing_utils::Materialize(credential_id_length)),
      credential_id_(std::move(credential_id)),
      public_key_(std::move(public_key)) {}

}  // namespace fido_device
}  // namespace cryptohome
