// Copyright 2017 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 "device/fido/attestation_statement_formats.h"

#include <utility>

#include "base/logging.h"
#include "device/fido/fido_parsing_utils.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"

namespace device {

namespace {
constexpr char kFidoFormatName[] = "fido-u2f";
constexpr char kPackedAttestationFormat[] = "packed";
constexpr char kAlgorithmKey[] = "alg";
constexpr char kSignatureKey[] = "sig";
constexpr char kX509CertKey[] = "x5c";

bool IsCertificateInappropriatelyIdentifying(
    const std::vector<uint8_t>& der_bytes) {
  constexpr int kVersionTag = 0;
  CBS cert(der_bytes);
  CBS top_level, to_be_signed_cert, issuer;
  if (!CBS_get_asn1(&cert, &top_level, CBS_ASN1_SEQUENCE) ||
      CBS_len(&cert) != 0 ||
      !CBS_get_asn1(&top_level, &to_be_signed_cert, CBS_ASN1_SEQUENCE) ||
      // version, explicitly tagged with tag zero.
      !CBS_get_optional_asn1(
          &to_be_signed_cert, NULL, NULL,
          CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | kVersionTag) ||
      // serialNumber
      !CBS_get_asn1(&to_be_signed_cert, NULL, CBS_ASN1_INTEGER) ||
      // signature algorithm
      !CBS_get_asn1(&to_be_signed_cert, NULL, CBS_ASN1_SEQUENCE) ||
      !CBS_get_asn1(&to_be_signed_cert, &issuer, CBS_ASN1_SEQUENCE)) {
    return false;
  }

  while (CBS_len(&issuer) != 0) {
    CBS relative_distinguished_names;
    if (!CBS_get_asn1(&issuer, &relative_distinguished_names, CBS_ASN1_SET)) {
      return false;
    }
    while (CBS_len(&relative_distinguished_names) != 0) {
      CBS relative_distinguished_name, object_id;
      if (!CBS_get_asn1(&relative_distinguished_names,
                        &relative_distinguished_name, CBS_ASN1_SEQUENCE) ||
          !CBS_get_asn1(&relative_distinguished_name, &object_id,
                        CBS_ASN1_OBJECT)) {
        return false;
      }

      // Encoding of OID 2.5.4.3 in DER form. See "OBJECT IDENTIFER" in
      // http://luca.ntop.org/Teaching/Appunti/asn1.html
      static constexpr uint8_t kCommonNameOID[] = {40 * 2 + 5, 4, 3};
      if (!CBS_mem_equal(&object_id, kCommonNameOID, sizeof(kCommonNameOID))) {
        continue;
      }

      CBS value;
      unsigned tag;
      if (!CBS_get_any_asn1(&relative_distinguished_name, &value, &tag)) {
        return false;
      }

      static constexpr uint8_t kCommonName[] = "FT FIDO 0100";
      if ((tag == CBS_ASN1_IA5STRING || tag == CBS_ASN1_UTF8STRING ||
           tag == CBS_ASN1_PRINTABLESTRING) &&
          CBS_mem_equal(&value, kCommonName, sizeof(kCommonName) - 1)) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace

// static
std::unique_ptr<FidoAttestationStatement>
FidoAttestationStatement::CreateFromU2fRegisterResponse(
    base::span<const uint8_t> u2f_data) {
  CBS response, cert;
  CBS_init(&response, u2f_data.data(), u2f_data.size());

  // The format of |u2f_data| is specified here:
  // https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-raw-message-formats-v1.2-ps-20170411.html#registration-response-message-success
  uint8_t credential_length;
  if (!CBS_skip(&response, kU2fKeyHandleLengthOffset) ||
      !CBS_get_u8(&response, &credential_length) ||
      !CBS_skip(&response, credential_length) ||
      !CBS_get_asn1_element(&response, &cert, CBS_ASN1_SEQUENCE)) {
    DLOG(ERROR)
        << "Invalid U2F response. Unable to unpack attestation statement.";
    return nullptr;
  }

  std::vector<std::vector<uint8_t>> x509_certificates;
  x509_certificates.emplace_back(CBS_data(&cert),
                                 CBS_data(&cert) + CBS_len(&cert));

  // The remaining bytes are the signature.
  std::vector<uint8_t> signature(CBS_data(&response),
                                 CBS_data(&response) + CBS_len(&response));
  return std::make_unique<FidoAttestationStatement>(
      std::move(signature), std::move(x509_certificates));
}

FidoAttestationStatement::FidoAttestationStatement(
    std::vector<uint8_t> signature,
    std::vector<std::vector<uint8_t>> x509_certificates)
    : AttestationStatement(kFidoFormatName),
      signature_(std::move(signature)),
      x509_certificates_(std::move(x509_certificates)) {}

FidoAttestationStatement::~FidoAttestationStatement() = default;

cbor::Value::MapValue FidoAttestationStatement::GetAsCBORMap() const {
  cbor::Value::MapValue attestation_statement_map;
  attestation_statement_map[cbor::Value(kSignatureKey)] =
      cbor::Value(signature_);

  std::vector<cbor::Value> certificate_array;
  for (const auto& cert : x509_certificates_) {
    certificate_array.push_back(cbor::Value(cert));
  }

  attestation_statement_map[cbor::Value(kX509CertKey)] =
      cbor::Value(std::move(certificate_array));

  return attestation_statement_map;
}

bool FidoAttestationStatement::IsSelfAttestation() {
  return false;
}

bool FidoAttestationStatement::
    IsAttestationCertificateInappropriatelyIdentifying() {
  // An attestation certificate is considered inappropriately identifying if it
  // contains a common name of "FT FIDO 0100". See "Inadequately batched
  // attestation certificates" on https://www.chromium.org/security-keys
  for (const auto& der_bytes : x509_certificates_) {
    if (IsCertificateInappropriatelyIdentifying(der_bytes)) {
      return true;
    }
  }

  return false;
}

base::Optional<base::span<const uint8_t>>
FidoAttestationStatement::GetLeafCertificate() const {
  if (x509_certificates_.empty()) {
    return base::nullopt;
  }
  return x509_certificates_[0];
}

PackedAttestationStatement::PackedAttestationStatement(
    CoseAlgorithmIdentifier algorithm,
    std::vector<uint8_t> signature,
    std::vector<std::vector<uint8_t>> x509_certificates)
    : AttestationStatement(kPackedAttestationFormat),
      algorithm_(algorithm),
      signature_(signature),
      x509_certificates_(std::move(x509_certificates)) {
  DCHECK(!signature_.empty());
}

PackedAttestationStatement::~PackedAttestationStatement() = default;

cbor::Value::MapValue PackedAttestationStatement::GetAsCBORMap() const {
  cbor::Value::MapValue attestation_statement_map;
  // alg
  attestation_statement_map[cbor::Value(kAlgorithmKey)] =
      cbor::Value(static_cast<int>(algorithm_));
  // sig
  attestation_statement_map[cbor::Value(kSignatureKey)] =
      cbor::Value(signature_);
  // x5c (optional)
  if (!x509_certificates_.empty()) {
    std::vector<cbor::Value> certificate_array;
    for (const auto& cert : x509_certificates_) {
      certificate_array.push_back(cbor::Value(cert));
    }
    attestation_statement_map[cbor::Value(kX509CertKey)] =
        cbor::Value(std::move(certificate_array));
  }
  return attestation_statement_map;
}

bool PackedAttestationStatement::IsSelfAttestation() {
  return x509_certificates_.empty();
}

bool PackedAttestationStatement::
    IsAttestationCertificateInappropriatelyIdentifying() {
  for (const auto& der_bytes : x509_certificates_) {
    if (IsCertificateInappropriatelyIdentifying(der_bytes)) {
      return true;
    }
  }

  return false;
}

base::Optional<base::span<const uint8_t>>
PackedAttestationStatement::GetLeafCertificate() const {
  if (x509_certificates_.empty()) {
    return base::nullopt;
  }
  return x509_certificates_[0];
}

}  // namespace device
