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

#include <utility>

#include "components/cbor/writer.h"
#include "components/device_event_log/device_event_log.h"
#include "device/fido/cbor_extract.h"
#include "device/fido/fido_constants.h"
#include "device/fido/public_key.h"
#include "third_party/boringssl/src/include/openssl/bn.h"
#include "third_party/boringssl/src/include/openssl/bytestring.h"
#include "third_party/boringssl/src/include/openssl/ec.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/mem.h"
#include "third_party/boringssl/src/include/openssl/obj.h"

using device::cbor_extract::IntKey;
using device::cbor_extract::Is;
using device::cbor_extract::StepOrByte;
using device::cbor_extract::Stop;

namespace device {

// kFieldElementLength is the size of a P-256 field element. The field is
// GF(2^256 - 2^224 + 2^192 + 2^96 - 1) and thus an element is 256 bits, or 32
// bytes.
constexpr size_t kFieldElementLength = 32;

// kUncompressedPointLength is the size of an X9.62 uncompressed point over
// P-256. It's one byte of type information followed by two field elements (x
// and y).
constexpr size_t kUncompressedPointLength = 1 + 2 * kFieldElementLength;

namespace {

// DERFromEC_POINT returns the ASN.1, DER, SubjectPublicKeyInfo for a given
// elliptic-curve point.
static std::vector<uint8_t> DERFromEC_POINT(const EC_POINT* point) {
  bssl::UniquePtr<EC_KEY> ec_key(
      EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
  CHECK(EC_KEY_set_public_key(ec_key.get(), point));
  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  CHECK(EVP_PKEY_assign_EC_KEY(pkey.get(), ec_key.release()));

  bssl::ScopedCBB cbb;
  uint8_t* der_bytes = nullptr;
  size_t der_bytes_len = 0;
  CHECK(CBB_init(cbb.get(), /* initial size */ 128) &&
        EVP_marshal_public_key(cbb.get(), pkey.get()) &&
        CBB_finish(cbb.get(), &der_bytes, &der_bytes_len));

  std::vector<uint8_t> ret(der_bytes, der_bytes + der_bytes_len);
  OPENSSL_free(der_bytes);
  return ret;
}

}  // namespace

// static
std::unique_ptr<PublicKey> P256PublicKey::ExtractFromU2fRegistrationResponse(
    int32_t algorithm,
    base::span<const uint8_t> u2f_data) {
  // In a U2F registration response, there is first a reserved byte that must be
  // ignored. Following that is the rest of the response.
  if (u2f_data.size() < 1 + kUncompressedPointLength) {
    return nullptr;
  }
  return ParseX962Uncompressed(algorithm,
                               u2f_data.subspan(1, kUncompressedPointLength));
}

// static
std::unique_ptr<PublicKey> P256PublicKey::ExtractFromCOSEKey(
    int32_t algorithm,
    base::span<const uint8_t> cbor_bytes,
    const cbor::Value::MapValue& map) {
  struct COSEKey {
    const int64_t* kty;
    const int64_t* crv;
    const std::vector<uint8_t>* x;
    const std::vector<uint8_t>* y;
  } cose_key;

  static constexpr cbor_extract::StepOrByte<COSEKey> kSteps[] = {
      // clang-format off
      ELEMENT(Is::kRequired, COSEKey, kty),
      IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kKty)),

      ELEMENT(Is::kRequired, COSEKey, crv),
      IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kEllipticCurve)),

      ELEMENT(Is::kRequired, COSEKey, x),
      IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kEllipticX)),

      ELEMENT(Is::kRequired, COSEKey, y),
      IntKey<COSEKey>(static_cast<int>(CoseKeyKey::kEllipticY)),

      Stop<COSEKey>(),
      // clang-format on
  };

  if (!cbor_extract::Extract<COSEKey>(&cose_key, kSteps, map) ||
      *cose_key.kty != static_cast<int64_t>(CoseKeyTypes::kEC2) ||
      *cose_key.crv != static_cast<int64_t>(CoseCurves::kP256) ||
      cose_key.x->size() != kFieldElementLength ||
      cose_key.y->size() != kFieldElementLength) {
    return nullptr;
  }

  bssl::UniquePtr<BIGNUM> x_bn(BN_new());
  bssl::UniquePtr<BIGNUM> y_bn(BN_new());
  if (!BN_bin2bn(cose_key.x->data(), cose_key.x->size(), x_bn.get()) ||
      !BN_bin2bn(cose_key.y->data(), cose_key.y->size(), y_bn.get())) {
    return nullptr;
  }

  // Parse into an |EC_POINT| to perform the validity checks that BoringSSL
  // does.
  bssl::UniquePtr<EC_GROUP> p256(
      EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
  if (!EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x_bn.get(),
                                           y_bn.get(), /*ctx=*/nullptr)) {
    FIDO_LOG(ERROR) << "P-256 public key is not on curve";
    return nullptr;
  }

  return std::make_unique<PublicKey>(algorithm, cbor_bytes,
                                     DERFromEC_POINT(point.get()));
}

// static
std::unique_ptr<PublicKey> P256PublicKey::ParseX962Uncompressed(
    int32_t algorithm,
    base::span<const uint8_t> x962) {
  // Parse into an |EC_POINT| to perform the validity checks that BoringSSL
  // does.
  bssl::UniquePtr<EC_GROUP> p256(
      EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(p256.get()));
  if (x962.size() != kUncompressedPointLength ||
      x962[0] != POINT_CONVERSION_UNCOMPRESSED ||
      !EC_POINT_oct2point(p256.get(), point.get(), x962.data(), x962.size(),
                          /*ctx=*/nullptr)) {
    FIDO_LOG(ERROR) << "P-256 public key is not on curve";
    return nullptr;
  }

  base::span<const uint8_t, kFieldElementLength> x(&x962[1],
                                                   kFieldElementLength);
  base::span<const uint8_t, kFieldElementLength> y(
      &x962[1 + kFieldElementLength], kFieldElementLength);

  cbor::Value::MapValue map;
  map.emplace(static_cast<int>(CoseKeyKey::kKty),
              static_cast<int64_t>(CoseKeyTypes::kEC2));
  map.emplace(static_cast<int>(CoseKeyKey::kAlg), algorithm);
  map.emplace(static_cast<int>(CoseKeyKey::kEllipticCurve),
              static_cast<int64_t>(CoseCurves::kP256));
  map.emplace(static_cast<int>(CoseKeyKey::kEllipticX), x);
  map.emplace(static_cast<int>(CoseKeyKey::kEllipticY), y);

  const std::vector<uint8_t> cbor_bytes(
      std::move(cbor::Writer::Write(cbor::Value(std::move(map))).value()));

  return std::make_unique<PublicKey>(algorithm, cbor_bytes,
                                     DERFromEC_POINT(point.get()));
}

}  // namespace device
