// Copyright 2019 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 "u2fd/util.h"

#include <array>
#include <string>
#include <utility>
#include <vector>

#include <base/logging.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>

namespace u2f {
namespace util {

template <>
void AppendToVector(const std::vector<uint8_t>& from,
                    std::vector<uint8_t>* to) {
  to->insert(to->end(), from.begin(), from.end());
}

template <>
void AppendToVector(const std::string& from, std::vector<uint8_t>* to) {
  to->insert(to->end(), from.begin(), from.end());
}

void AppendSubstringToVector(const std::string& from,
                             int start,
                             int length,
                             std::vector<uint8_t>* to) {
  to->insert(to->end(), from.begin() + start, from.begin() + start + length);
}

base::Optional<std::vector<uint8_t>> SignatureToDerBytes(const uint8_t* r,
                                                         const uint8_t* s) {
  crypto::ScopedBIGNUM sig_r(BN_new()), sig_s(BN_new());
  crypto::ScopedECDSA_SIG sig(ECDSA_SIG_new());
  if (!sig_r || !sig_s || !sig) {
    LOG(ERROR) << "Failed to allocate ECDSA_SIG or BIGNUM.";
    return base::nullopt;
  }
  if (!BN_bin2bn(r, 32, sig_r.get()) ||
      !BN_bin2bn(s, 32, sig_s.get())) {
    LOG(ERROR) << "Failed to convert ECDSA_SIG parameters to BIGNUM";
    return base::nullopt;
  }

  if (!ECDSA_SIG_set0(sig.get(), sig_r.release(), sig_s.release())) {
    LOG(ERROR) << "Failed to initialize ECDSA_SIG";
    return base::nullopt;
  }

  int sig_len = i2d_ECDSA_SIG(sig.get(), nullptr);

  std::vector<uint8_t> signature(sig_len);
  uint8_t* sig_ptr = &signature[0];

  if (i2d_ECDSA_SIG(sig.get(), &sig_ptr) != sig_len) {
    LOG(ERROR) << "DER encoding returned unexpected length";
    return base::nullopt;
  }

  return signature;
}

crypto::ScopedEC_KEY CreateAttestationKey() {
  crypto::ScopedEC_KEY key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
  EC_KEY_set_asn1_flag(key.get(), OPENSSL_EC_NAMED_CURVE);

  if (!key || !EC_KEY_generate_key(key.get())) {
    LOG(ERROR) << "Failed to generate U2F attestation key.";
    return nullptr;
  } else {
    return key;
  }
}

base::Optional<std::vector<uint8_t>> AttestToData(
    const std::vector<uint8_t>& data, EC_KEY* attestation_key) {
  std::vector<uint8_t> digest = Sha256(data);

  std::vector<uint8_t> signature(ECDSA_size(attestation_key));
  unsigned int signature_length;

  if (!ECDSA_sign(0 /* type: ignored by OpenSSL */, &digest[0], digest.size(),
                  signature.data(), &signature_length, attestation_key)) {
    LOG(ERROR) << "Failed to sign data using U2F attestation key";
    return base::nullopt;
  }

  signature.resize(signature_length);
  return signature;
}

namespace {

template <typename C>
crypto::ScopedOpenSSL<X509, X509_free> ParseX509(const C& container) {
  const unsigned char* parse_ptr =
      static_cast<const unsigned char*>(&container[0]);

  crypto::ScopedOpenSSL<X509, X509_free> cert(
      d2i_X509(nullptr /* create and return new X509 struct */, &parse_ptr,
               container.size()));

  if (!cert) {
    LOG(ERROR) << "Failed to parse X509 certificate.";
  }

  return cert;
}

base::Optional<std::vector<uint8_t>> DerEncodeCertificate(X509* cert) {
  int cert_size = i2d_X509(cert, nullptr);
  if (cert_size < 0) {
    LOG(ERROR) << "Failed to DER-encode X509 certficate, error: " << cert_size;
    return base::nullopt;
  }

  std::vector<uint8_t> cert_der(cert_size);
  unsigned char* output_ptr = &cert_der[0];

  if (i2d_X509(cert, &output_ptr) != cert_size) {
    LOG(ERROR) << "X509 DER-encoding returned unexpected size, expected "
               << cert_size;
    return base::nullopt;
  }

  return cert_der;
}

}  // namespace

base::Optional<std::vector<uint8_t>> CreateAttestationCertificate(
    EC_KEY* attestation_key) {
  // We use a fixed template for the X509 certificate rather than generating one
  // using OpenSSL, so that we can ensure that u2fd and cr50 both return
  // certificates with the same structure.
  // The array below is generated by the openssl tool from the template in
  // x509_tmpl.txt.
  constexpr std::array<unsigned char, 164> cert_template = {
      0x30, 0x81, 0xA1, 0x30, 0x81, 0x8E, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02,
      0x01, 0x00, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04,
      0x03, 0x02, 0x30, 0x0F, 0x31, 0x0D, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x04,
      0x03, 0x13, 0x04, 0x63, 0x72, 0x35, 0x30, 0x30, 0x22, 0x18, 0x0F, 0x32,
      0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
      0x30, 0x5A, 0x18, 0x0F, 0x32, 0x30, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31,
      0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x0F, 0x31, 0x0D, 0x30,
      0x0B, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x63, 0x72, 0x35, 0x30,
      0x30, 0x19, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02,
      0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03,
      0x02, 0x00, 0x00, 0xA3, 0x17, 0x30, 0x15, 0x30, 0x13, 0x06, 0x0B, 0x2B,
      0x06, 0x01, 0x04, 0x01, 0x82, 0xE5, 0x1C, 0x02, 0x01, 0x01, 0x04, 0x04,
      0x03, 0x02, 0x03, 0x08, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE,
      0x3D, 0x04, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00,
  };

  crypto::ScopedOpenSSL<X509, X509_free> cert = ParseX509(cert_template);
  if (!cert) {
    return base::nullopt;
  }

  crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new());
  if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), attestation_key)) {
    LOG(ERROR) << "Failed to create EVP_PKEY";
    return base::nullopt;
  }

  if (!X509_set_pubkey(cert.get(), pkey.get()) ||
      X509_sign(cert.get(), pkey.get(), EVP_sha256()) <=
          0 /* returns length on succes */) {
    LOG(ERROR) << "Failed to update X509 pubkey and signature fields";
    return base::nullopt;
  }

  return DerEncodeCertificate(cert.get());
}

bool RemoveCertificatePadding(std::vector<uint8_t>* cert_in) {
  const unsigned char* cert_start = &cert_in->front();
  const unsigned char* parse_ptr = cert_start;

  crypto::ScopedOpenSSL<X509, X509_free> cert(
      d2i_X509(nullptr /* create and return new X509 struct */, &parse_ptr,
               cert_in->size()));

  if (!cert) {
    LOG(ERROR) << "Failed to parse X509 certificate.";
    return false;
  }

  size_t cert_size = parse_ptr - cert_start;

  if (cert_size > cert_in->size()) {
    LOG(ERROR) << "Unexpectedly parsed X509 cert larger than input buffer.";
    return false;
  }

  cert_in->resize(cert_size);
  return true;
}

}  // namespace util
}  // namespace u2f
