// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
#include "tink/subtle/pem_parser_boringssl.h"

#include <memory>

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "openssl/base.h"
#include "openssl/bio.h"
#include "openssl/bn.h"
#include "openssl/evp.h"
#include "openssl/pem.h"
#include "openssl/rsa.h"
#include "tink/subtle/common_enums.h"
#include "tink/subtle/subtle_util_boringssl.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"

namespace crypto {
namespace tink {
namespace subtle {

namespace {
constexpr int kBsslOk = 1;

// Verifies that the given RSA pointer `rsa_key` points to a valid RSA key.
util::Status VerifyRsaKey(const RSA *rsa_key) {
  if (rsa_key == nullptr) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "Invalid RSA key format");
  }
  // Check the key parameters.
  if (RSA_check_key(rsa_key) != kBsslOk) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "Invalid RSA key format");
  }
  return util::OkStatus();
}

// Converts the public portion of a given SubtleUtilBoringSSL::EcKey,
// `subtle_ec_key`, into an OpenSSL EC key, `openssl_ec_key`.
util::Status ConvertSubtleEcKeyToOpenSslEcPublicKey(
    const SubtleUtilBoringSSL::EcKey& subtle_ec_key, EC_KEY* openssl_ec_key) {
  if (openssl_ec_key == nullptr) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "`openssl_ec_key` arg cannot be NULL");
  }

  // Set the key's group (EC curve).
  auto group_statusor = SubtleUtilBoringSSL::GetEcGroup(subtle_ec_key.curve);
  if (!group_statusor.ok()) {
    return group_statusor.status();
  }
  bssl::UniquePtr<EC_GROUP> group(group_statusor.ValueOrDie());
  if (group.get() == nullptr) {
    return util::Status(
        util::error::INTERNAL,
        absl::StrCat("failed to set EC group to curve ", subtle_ec_key.curve));
  }
  if (!EC_KEY_set_group(openssl_ec_key, group.get())) {
    return util::Status(
        util::error::INTERNAL,
        absl::StrCat("failed to set key group from EC group for curve ",
                     subtle_ec_key.curve));
  }

  // Create an EC point and initialize it from the key proto.
  bssl::UniquePtr<EC_POINT> point(EC_POINT_new(group.get()));
  if (!point.get()) {
    return util::Status(util::error::INTERNAL, "failed to allocate EC_POINT");
  }
  bssl::UniquePtr<BIGNUM> x(BN_bin2bn(
      reinterpret_cast<const unsigned char*>(subtle_ec_key.pub_x.data()),
      subtle_ec_key.pub_x.length(), nullptr));
  bssl::UniquePtr<BIGNUM> y(BN_bin2bn(
      reinterpret_cast<const unsigned char*>(subtle_ec_key.pub_y.data()),
      subtle_ec_key.pub_y.length(), nullptr));
  if (!EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(), x.get(),
                                           y.get(), nullptr)) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed to set affine coordinates");
  }
  if (!EC_POINT_is_on_curve(group.get(), point.get(), nullptr)) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed to confirm EC point is on curve");
  }

  // Set the key's point from the EC point, created above.
  if (!EC_KEY_set_public_key(openssl_ec_key, point.get())) {
    return util::Status(util::error::INTERNAL, "failed to set public key");
  }

  return util::OkStatus();
}

// Converts a given SubtleUtilBoringSSL::EcKey, `subtle_ec_key`, into an OpenSSL
// EC key, `openssl_ec_key`.
util::Status ConvertSubtleEcKeyToOpenSslEcPrivateKey(
    const SubtleUtilBoringSSL::EcKey& subtle_ec_key, EC_KEY* openssl_ec_key) {
  if (openssl_ec_key == nullptr) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "`openssl_ec_key` arg cannot be NULL");
  }
  util::Status status =
      ConvertSubtleEcKeyToOpenSslEcPublicKey(subtle_ec_key, openssl_ec_key);
  if (!status.ok()) {
    return status;
  }
  bssl::UniquePtr<BIGNUM> x(BN_bin2bn(
      reinterpret_cast<const unsigned char*>(subtle_ec_key.priv.data()),
      subtle_ec_key.priv.size(), nullptr));
  if (!EC_KEY_set_private_key(openssl_ec_key, x.get())) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed to set private key");
  }
  if (!EC_KEY_check_key(openssl_ec_key)) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed private key check");
  }
  return util::OkStatus();
}

// Converts an OpenSSL BIO (i.e., basic IO stream), `bio`, into a string.
util::StatusOr<std::string> ConvertBioToString(BIO* bio) {
  BUF_MEM* mem = nullptr;
  BIO_get_mem_ptr(bio, &mem);
  std::string pem_material;
  if (mem->data && mem->length) {
    pem_material.assign(mem->data, mem->length);
  }
  if (pem_material.empty()) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed to retrieve key material from BIO");
  }
  return pem_material;
}

}  // namespace

// static.
util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::RsaPublicKey>>
PemParser::ParseRsaPublicKey(absl::string_view pem_serialized_key) {
  // Read the RSA key into EVP_PKEY.
  bssl::UniquePtr<BIO> rsa_key_bio(BIO_new(BIO_s_mem()));
  BIO_write(rsa_key_bio.get(), pem_serialized_key.data(),
            pem_serialized_key.size());

  bssl::UniquePtr<EVP_PKEY> evp_rsa_key(PEM_read_bio_PUBKEY(
      rsa_key_bio.get(), /*x=*/nullptr, /*cb=*/nullptr, /*u=*/nullptr));

  if (evp_rsa_key == nullptr) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "PEM Public Key parsing failed");
  }
  // No need to free bssl_rsa_key after use.
  RSA *bssl_rsa_key = EVP_PKEY_get0_RSA(evp_rsa_key.get());
  auto is_valid = VerifyRsaKey(bssl_rsa_key);
  if (!is_valid.ok()) {
    return is_valid;
  }

  // Get the public key paramters.
  const BIGNUM *n_bn, *e_bn, *d_bn;
  RSA_get0_key(bssl_rsa_key, &n_bn, &e_bn, &d_bn);

  // Public key should not have d_bn set.
  if (d_bn != nullptr) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "Invalid RSA Public Key format");
  }

  // We are only interested in e and n.
  auto n_str_statusor = SubtleUtilBoringSSL::bn2str(n_bn, BN_num_bytes(n_bn));
  auto e_str_statusor = SubtleUtilBoringSSL::bn2str(e_bn, BN_num_bytes(e_bn));
  if (!n_str_statusor.ok()) return n_str_statusor.status();
  if (!e_str_statusor.ok()) return e_str_statusor.status();
  auto rsa_public_key = absl::make_unique<SubtleUtilBoringSSL::RsaPublicKey>();
  rsa_public_key->e = std::move(e_str_statusor.ValueOrDie());
  rsa_public_key->n = std::move(n_str_statusor.ValueOrDie());

  return rsa_public_key;
}

// static.
util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::RsaPrivateKey>>
PemParser::ParseRsaPrivateKey(absl::string_view pem_serialized_key) {
  // Read the private key into EVP_PKEY.
  bssl::UniquePtr<BIO> rsa_key_bio(BIO_new(BIO_s_mem()));
  BIO_write(rsa_key_bio.get(), pem_serialized_key.data(),
            pem_serialized_key.size());

  // BoringSSL APIs to parse the PEM data.
  bssl::UniquePtr<EVP_PKEY> evp_rsa_key(PEM_read_bio_PrivateKey(
      rsa_key_bio.get(), /*x=*/nullptr, /*cb=*/nullptr, /*u=*/nullptr));

  if (evp_rsa_key == nullptr) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "PEM Private Key parsing failed");
  }

  // No need to free bssl_rsa_key after use.
  RSA *bssl_rsa_key = EVP_PKEY_get0_RSA(evp_rsa_key.get());

  auto is_valid_key = VerifyRsaKey(bssl_rsa_key);
  if (!is_valid_key.ok()) {
    return is_valid_key;
  }

  const BIGNUM *n_bn, *e_bn, *d_bn;
  RSA_get0_key(bssl_rsa_key, &n_bn, &e_bn, &d_bn);

  // Save exponents.
  auto rsa_private_key =
      absl::make_unique<SubtleUtilBoringSSL::RsaPrivateKey>();
  auto n_str = SubtleUtilBoringSSL::bn2str(n_bn, BN_num_bytes(n_bn));
  auto e_str = SubtleUtilBoringSSL::bn2str(e_bn, BN_num_bytes(e_bn));
  auto d_str =
      SubtleUtilBoringSSL::BignumToSecretData(d_bn, BN_num_bytes(d_bn));
  if (!n_str.ok()) return n_str.status();
  if (!e_str.ok()) return e_str.status();
  if (!d_str.ok()) return d_str.status();
  rsa_private_key->n = std::move(n_str.ValueOrDie());
  rsa_private_key->e = std::move(e_str.ValueOrDie());
  rsa_private_key->d = std::move(d_str.ValueOrDie());

  // Save factors.
  const BIGNUM *p_bn, *q_bn;
  RSA_get0_factors(bssl_rsa_key, &p_bn, &q_bn);
  auto p_str =
      SubtleUtilBoringSSL::BignumToSecretData(p_bn, BN_num_bytes(p_bn));
  auto q_str =
      SubtleUtilBoringSSL::BignumToSecretData(q_bn, BN_num_bytes(q_bn));
  if (!p_str.ok()) return p_str.status();
  if (!q_str.ok()) return q_str.status();
  rsa_private_key->p = std::move(p_str.ValueOrDie());
  rsa_private_key->q = std::move(q_str.ValueOrDie());

  // Save CRT parameters.
  const BIGNUM *dp_bn, *dq_bn, *crt_bn;
  RSA_get0_crt_params(bssl_rsa_key, &dp_bn, &dq_bn, &crt_bn);
  auto dp_str =
      SubtleUtilBoringSSL::BignumToSecretData(dp_bn, BN_num_bytes(dp_bn));
  auto dq_str =
      SubtleUtilBoringSSL::BignumToSecretData(dq_bn, BN_num_bytes(dq_bn));
  auto crt_str =
      SubtleUtilBoringSSL::BignumToSecretData(crt_bn, BN_num_bytes(crt_bn));
  if (!dp_str.ok()) return dp_str.status();
  if (!dq_str.ok()) return dq_str.status();
  if (!crt_str.ok()) return crt_str.status();
  rsa_private_key->dp = std::move(dp_str.ValueOrDie());
  rsa_private_key->dq = std::move(dq_str.ValueOrDie());
  rsa_private_key->crt = std::move(crt_str.ValueOrDie());

  return rsa_private_key;
}

util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>>
PemParser::ParseEcPublicKey(absl::string_view pem_serialized_key) {
  return util::Status(util::error::UNIMPLEMENTED,
                      "PEM EC Public Key parsing is unimplemented");
}

util::StatusOr<std::unique_ptr<SubtleUtilBoringSSL::EcKey>>
PemParser::ParseEcPrivateKey(absl::string_view pem_serialized_key) {
  return util::Status(util::error::UNIMPLEMENTED,
                      "PEM EC Private Key parsing is unimplemented");
}

util::StatusOr<std::string> PemParser::WriteEcPublicKey(
    const SubtleUtilBoringSSL::EcKey& ec_key) {
  bssl::UniquePtr<EC_KEY> openssl_ec_key(EC_KEY_new());
  util::Status status =
      ConvertSubtleEcKeyToOpenSslEcPublicKey(ec_key, openssl_ec_key.get());
  if (!status.ok()) {
    return status;
  }
  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
  if (!PEM_write_bio_EC_PUBKEY(bio.get(), openssl_ec_key.get())) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed to write openssl EC key to write bio");
  }
  return ConvertBioToString(bio.get());
}

util::StatusOr<std::string> PemParser::WriteEcPrivateKey(
    const SubtleUtilBoringSSL::EcKey& ec_key) {
  bssl::UniquePtr<EC_KEY> openssl_ec_key(EC_KEY_new());
  util::Status status =
      ConvertSubtleEcKeyToOpenSslEcPrivateKey(ec_key, openssl_ec_key.get());
  if (!status.ok()) {
    return status;
  }
  bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
  if (!PEM_write_bio_ECPrivateKey(bio.get(), openssl_ec_key.get(),
                                  /*enc=*/nullptr, /*kstr=*/nullptr, /*klen=*/0,
                                  /*cb=*/nullptr, /*u=*/nullptr)) {
    return util::Status(util::error::INVALID_ARGUMENT,
                        "failed to write openssl EC key to write bio");
  }
  return ConvertBioToString(bio.get());
}

}  // namespace subtle
}  // namespace tink
}  // namespace crypto
