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

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

#include <base/containers/span.h>
#include <base/logging.h>
#include <base/optional.h>
#include <base/strings/string_number_conversions.h>
#include <chromeos/cbor/reader.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/obj_mac.h>

#include "cryptohome/fido/fido_constants.h"

namespace cryptohome {
namespace fido_device {

std::unique_ptr<ECPublicKey> ECPublicKey::ParseECPublicKey(
    base::span<const uint8_t> cose_encoded_public_key) {
  std::unique_ptr<ECPublicKey> ec_key(new ECPublicKey());
  if (!ec_key->ParseCOSE(cose_encoded_public_key))
    return nullptr;

  // Save the cose string.
  std::vector<uint8_t> bytes(cose_encoded_public_key.begin(),
                             cose_encoded_public_key.end());
  ec_key->SetCOSEKey(bytes);

  return ec_key;
}

ECPublicKey::ECPublicKey() {}

std::vector<uint8_t> ECPublicKey::EncodeAsCOSEKey() const {
  return cose_encoding_;
}

void ECPublicKey::SetCOSEKey(const std::vector<uint8_t> cose_key) {
  cose_encoding_ = cose_key;
}

bool ECPublicKey::ParseCOSE(base::span<const uint8_t> bytes) {
  size_t bytes_read;
  base::Optional<cbor::Value> value = cbor::Reader::Read(bytes, &bytes_read);

  if (!value || !value->is_map()) {
    LOG(ERROR) << "Failed to parse public key, "
               << "COSE key should be a valid CBOR map";
    return false;
  }

  auto& cose_key = value->GetMap();

  // This is the only format we support now.
  for (const auto& pair : std::vector<std::pair<int, int>>({
           {1 /* key type */, 2 /* elliptic curve, uncompressed */},
           {3 /* algorithm */,
            static_cast<int>(CoseAlgorithmIdentifier::kCoseEs256)},
           {-1 /* curve */, 1 /* P-256 */},
       })) {
    auto it = cose_key.find(cbor::Value(pair.first));
    if (it == cose_key.end() || !it->second.is_integer() ||
        it->second.GetInteger() != pair.second) {
      LOG(ERROR) << "Failed to parse COSE when parsing key: "
                 << it->first.GetInteger()
                 << " value: " << it->second.GetInteger()
                 << ", only uncompressed EC P-256 public key is supported";
      return false;
    }
  }

  algorithm_ = kEccAlgName;

  // See https://tools.ietf.org/html/rfc8152#section-13.1.1
  const auto& x_it = cose_key.find(cbor::Value(-2));
  const auto& y_it = cose_key.find(cbor::Value(-3));

  if (x_it == cose_key.end() || y_it == cose_key.end() ||
      !x_it->second.is_bytestring() || !y_it->second.is_bytestring()) {
    return false;
  }
  x_ = x_it->second.GetBytestring();
  y_ = y_it->second.GetBytestring();
  return true;
}

bool ECPublicKey::DumpToDer(brillo::SecureBlob* der) {
  crypto::ScopedEC_Key pub_key = GetEC_KEY();
  if (!pub_key) {
    LOG(ERROR) << "Failed to create public key";
    return false;
  }

  int pub_key_len = i2d_EC_PUBKEY(pub_key.get(), NULL /* get size */);
  if (pub_key_len <= 0) {
    LOG(ERROR) << "Invalid EC_PUBKEY length: " << pub_key_len;
    return false;
  }

  der->resize(pub_key_len);
  unsigned char* der_buffer = der->data();
  pub_key_len = i2d_EC_PUBKEY(pub_key.get(), &der_buffer);
  if (pub_key_len < 0) {
    LOG(ERROR) << "Failed to encode to DER format.";
    return false;
  }
  der->resize(pub_key_len);
  return true;
}

crypto::ScopedEC_Key ECPublicKey::GetEC_KEY() const {
  crypto::ScopedEC_Key ecc_key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
  const EC_GROUP* group = EC_KEY_get0_group(ecc_key.get());
  crypto::ScopedEC_POINT public_key(EC_POINT_new(group));

  crypto::ScopedBIGNUM x(BN_bin2bn(x_.data(), x_.size(), nullptr));
  crypto::ScopedBIGNUM y(BN_bin2bn(y_.data(), y_.size(), nullptr));

  if (!EC_POINT_set_affine_coordinates_GFp(group, public_key.get(), x.release(),
                                           y.release(), nullptr)) {
    LOG(ERROR) << "Failed to set affine coordinates GFp.";
    return nullptr;
  }
  if (!EC_KEY_set_public_key(ecc_key.get(), public_key.release())) {
    LOG(ERROR) << "Failed to set public key for EC_KEY.";
    return nullptr;
  }
  EC_KEY_set_asn1_flag(ecc_key.get(), OPENSSL_EC_NAMED_CURVE);

  if (!EC_KEY_check_key(ecc_key.get())) {
    LOG(ERROR) << "Invalid EC public key, please make sure the public key is "
               << "on curve.";
    return nullptr;
  }
  return ecc_key;
}

std::string ECPublicKey::ToString() {
  std::stringstream ss;
  ss << "EC P256 public key, x = " << base::HexEncode(x_.data(), x_.size())
     << ", y = " << base::HexEncode(y_.data(), y_.size());

  return ss.str();
}

BinaryValue ECPublicKey::GetX() const {
  return x_;
}

BinaryValue ECPublicKey::GetY() const {
  return y_;
}

base::Optional<int> ECPublicKey::GetAlgorithmNid() const {
  if (algorithm_ == "ES256")
    return NID_X9_62_prime256v1;

  return base::nullopt;
}

}  // namespace fido_device
}  // namespace cryptohome
