// Copyright (c) 2021 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 <windows.h>

#include <ncrypt.h>

#include <string>
#include <tuple>
#include <vector>

#include "base/logging.h"
#include "base/numerics/checked_math.h"
#include "base/scoped_generic.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/scoped_blocking_call.h"
#include "crypto/random.h"
#include "crypto/sha2.h"
#include "crypto/unexportable_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/ec_key.h"
#include "third_party/boringssl/src/include/openssl/ecdsa.h"
#include "third_party/boringssl/src/include/openssl/evp.h"
#include "third_party/boringssl/src/include/openssl/nid.h"
#include "third_party/boringssl/src/include/openssl/rsa.h"

namespace crypto {

namespace {

// NCrypt has a style of returning handles by writing opaque pointers to
// caller-provided locations. These pointers must be passed to
// |NCryptFreeObject| when no longer needed.
template <typename T>
struct NCryptObjectTraits {
  // In practice a value of zero makes |NCryptFreeObject| a no-op, but this
  // isn't specified by the documentation so the code below avoids depending on
  // this by releasing() values that were never initialised.
  static T InvalidValue() { return 0; }
  static void Free(T handle) { NCryptFreeObject(handle); }
};

using ScopedProvider =
    base::ScopedGeneric<NCRYPT_PROV_HANDLE,
                        NCryptObjectTraits<NCRYPT_PROV_HANDLE>>;
using ScopedKey = base::ScopedGeneric<NCRYPT_KEY_HANDLE,
                                      NCryptObjectTraits<NCRYPT_KEY_HANDLE>>;

std::vector<uint8_t> CBBToVector(const CBB* cbb) {
  return std::vector<uint8_t>(CBB_data(cbb), CBB_data(cbb) + CBB_len(cbb));
}

// BCryptAlgorithmFor returns the BCrypt algorithm ID for the given Chromium
// signing algorithm.
absl::optional<LPCWSTR> BCryptAlgorithmFor(
    SignatureVerifier::SignatureAlgorithm algo) {
  switch (algo) {
    case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
      return BCRYPT_RSA_ALGORITHM;

    case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
      return BCRYPT_ECDSA_P256_ALGORITHM;

    default:
      return absl::nullopt;
  }
}

// GetBestSupported returns the first element of |acceptable_algorithms| that
// |provider| supports, or |nullopt| if there isn't any.
absl::optional<SignatureVerifier::SignatureAlgorithm> GetBestSupported(
    NCRYPT_PROV_HANDLE provider,
    base::span<const SignatureVerifier::SignatureAlgorithm>
        acceptable_algorithms) {
  for (auto algo : acceptable_algorithms) {
    absl::optional<LPCWSTR> bcrypto_algo_name = BCryptAlgorithmFor(algo);
    if (!bcrypto_algo_name) {
      continue;
    }

    if (!FAILED(NCryptIsAlgSupported(provider, *bcrypto_algo_name,
                                     /*flags=*/0))) {
      return algo;
    }
  }

  return absl::nullopt;
}

// GetKeyProperty returns the given NCrypt key property of |key|.
absl::optional<std::vector<uint8_t>> GetKeyProperty(NCRYPT_KEY_HANDLE key,
                                                    LPCWSTR property) {
  DWORD size;
  if (FAILED(NCryptGetProperty(key, property, nullptr, 0, &size, 0))) {
    return absl::nullopt;
  }

  std::vector<uint8_t> ret(size);
  if (FAILED(
          NCryptGetProperty(key, property, ret.data(), ret.size(), &size, 0))) {
    return absl::nullopt;
  }
  CHECK_EQ(ret.size(), size);

  return ret;
}

// ExportKey returns |key| exported in the given format or nullopt on error.
absl::optional<std::vector<uint8_t>> ExportKey(NCRYPT_KEY_HANDLE key,
                                               LPCWSTR format) {
  DWORD output_size;
  if (FAILED(NCryptExportKey(key, 0, format, nullptr, nullptr, 0, &output_size,
                             0))) {
    return absl::nullopt;
  }

  std::vector<uint8_t> output(output_size);
  if (FAILED(NCryptExportKey(key, 0, format, nullptr, output.data(),
                             output.size(), &output_size, 0))) {
    return absl::nullopt;
  }
  CHECK_EQ(output.size(), output_size);

  return output;
}

absl::optional<std::vector<uint8_t>> GetP256ECDSASPKI(NCRYPT_KEY_HANDLE key) {
  const absl::optional<std::vector<uint8_t>> pub_key =
      ExportKey(key, BCRYPT_ECCPUBLIC_BLOB);
  if (!pub_key) {
    return absl::nullopt;
  }

  // The exported key is a |BCRYPT_ECCKEY_BLOB| followed by the bytes of the
  // public key itself.
  // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_ecckey_blob
  BCRYPT_ECCKEY_BLOB header;
  if (pub_key->size() < sizeof(header)) {
    return absl::nullopt;
  }
  memcpy(&header, pub_key->data(), sizeof(header));
  // |cbKey| is documented[1] as "the length, in bytes, of the key". It is
  // not. For ECDSA public keys it is the length of a field element.
  if (header.dwMagic != BCRYPT_ECDSA_PUBLIC_P256_MAGIC ||
      header.cbKey != 256 / 8 ||
      pub_key->size() - sizeof(BCRYPT_ECCKEY_BLOB) != 64) {
    return absl::nullopt;
  }

  uint8_t x962[1 + 32 + 32];
  x962[0] = POINT_CONVERSION_UNCOMPRESSED;
  memcpy(&x962[1], pub_key->data() + sizeof(BCRYPT_ECCKEY_BLOB), 64);

  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_oct2point(p256.get(), point.get(), x962, sizeof(x962),
                          /*ctx=*/nullptr)) {
    return absl::nullopt;
  }
  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.get()));
  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  CHECK(EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()));

  bssl::ScopedCBB cbb;
  CHECK(CBB_init(cbb.get(), /*initial_capacity=*/128) &&
        EVP_marshal_public_key(cbb.get(), pkey.get()));
  return CBBToVector(cbb.get());
}

absl::optional<std::vector<uint8_t>> GetRSASPKI(NCRYPT_KEY_HANDLE key) {
  const absl::optional<std::vector<uint8_t>> pub_key =
      ExportKey(key, BCRYPT_RSAPUBLIC_BLOB);
  if (!pub_key) {
    return absl::nullopt;
  }

  // The exported key is a |BCRYPT_RSAKEY_BLOB| followed by the bytes of the
  // key itself.
  // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob
  BCRYPT_RSAKEY_BLOB header;
  if (pub_key->size() < sizeof(header)) {
    return absl::nullopt;
  }
  memcpy(&header, pub_key->data(), sizeof(header));
  if (header.Magic != static_cast<ULONG>(BCRYPT_RSAPUBLIC_MAGIC)) {
    return absl::nullopt;
  }

  size_t bytes_needed;
  if (!base::CheckAdd(sizeof(BCRYPT_RSAKEY_BLOB),
                      base::CheckAdd(header.cbPublicExp, header.cbModulus))
           .AssignIfValid(&bytes_needed) ||
      pub_key->size() < bytes_needed) {
    return absl::nullopt;
  }

  bssl::UniquePtr<BIGNUM> e(
      BN_bin2bn(&pub_key->data()[sizeof(BCRYPT_RSAKEY_BLOB)],
                header.cbPublicExp, nullptr));
  bssl::UniquePtr<BIGNUM> n(BN_bin2bn(
      &pub_key->data()[sizeof(BCRYPT_RSAKEY_BLOB) + header.cbPublicExp],
      header.cbModulus, nullptr));

  bssl::UniquePtr<RSA> rsa(RSA_new());
  CHECK(RSA_set0_key(rsa.get(), n.release(), e.release(), nullptr));
  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
  CHECK(EVP_PKEY_set1_RSA(pkey.get(), rsa.get()));

  bssl::ScopedCBB cbb;
  CHECK(CBB_init(cbb.get(), /*initial_capacity=*/384) &&
        EVP_marshal_public_key(cbb.get(), pkey.get()));
  return CBBToVector(cbb.get());
}

// ECDSAKey wraps a TPM-stored P-256 ECDSA key.
class ECDSAKey : public UnexportableSigningKey {
 public:
  ECDSAKey(ScopedProvider provider,
           ScopedKey key,
           std::vector<uint8_t> wrapped,
           std::vector<uint8_t> spki)
      : provider_(std::move(provider)),
        key_(std::move(key)),
        wrapped_(std::move(wrapped)),
        spki_(std::move(spki)) {}

  SignatureVerifier::SignatureAlgorithm Algorithm() const override {
    return SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256;
  }

  std::vector<uint8_t> GetSubjectPublicKeyInfo() const override {
    return spki_;
  }

  std::vector<uint8_t> GetWrappedKey() const override { return wrapped_; }

  absl::optional<std::vector<uint8_t>> SignSlowly(
      base::span<const uint8_t> data) override {
    base::ScopedBlockingCall scoped_blocking_call(
        FROM_HERE, base::BlockingType::WILL_BLOCK);

    std::array<uint8_t, kSHA256Length> digest = SHA256Hash(data);
    // The signature is written as a pair of big-endian field elements for P-256
    // ECDSA.
    std::vector<uint8_t> sig(64);
    DWORD sig_size;
    if (FAILED(NCryptSignHash(key_.get(), nullptr, digest.data(), digest.size(),
                              sig.data(), sig.size(), &sig_size,
                              NCRYPT_SILENT_FLAG))) {
      return absl::nullopt;
    }
    CHECK_EQ(sig.size(), sig_size);

    bssl::UniquePtr<BIGNUM> r(BN_bin2bn(sig.data(), 32, nullptr));
    bssl::UniquePtr<BIGNUM> s(BN_bin2bn(sig.data() + 32, 32, nullptr));
    ECDSA_SIG sig_st;
    sig_st.r = r.get();
    sig_st.s = s.get();

    bssl::ScopedCBB cbb;
    CHECK(CBB_init(cbb.get(), /*initial_capacity=*/72) &&
          ECDSA_SIG_marshal(cbb.get(), &sig_st));
    return CBBToVector(cbb.get());
  }

 private:
  ScopedProvider provider_;
  ScopedKey key_;
  const std::vector<uint8_t> wrapped_;
  const std::vector<uint8_t> spki_;
};

// RSAKey wraps a TPM-stored RSA key.
class RSAKey : public UnexportableSigningKey {
 public:
  RSAKey(ScopedProvider provider,
         ScopedKey key,
         std::vector<uint8_t> wrapped,
         std::vector<uint8_t> spki)
      : provider_(std::move(provider)),
        key_(std::move(key)),
        wrapped_(std::move(wrapped)),
        spki_(std::move(spki)) {}

  SignatureVerifier::SignatureAlgorithm Algorithm() const override {
    return SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256;
  }

  std::vector<uint8_t> GetSubjectPublicKeyInfo() const override {
    return spki_;
  }

  std::vector<uint8_t> GetWrappedKey() const override { return wrapped_; }

  absl::optional<std::vector<uint8_t>> SignSlowly(
      base::span<const uint8_t> data) override {
    base::ScopedBlockingCall scoped_blocking_call(
        FROM_HERE, base::BlockingType::WILL_BLOCK);

    std::array<uint8_t, kSHA256Length> digest = SHA256Hash(data);
    BCRYPT_PKCS1_PADDING_INFO padding_info = {0};
    padding_info.pszAlgId = NCRYPT_SHA256_ALGORITHM;

    DWORD sig_size;
    if (FAILED(NCryptSignHash(key_.get(), &padding_info, digest.data(),
                              digest.size(), nullptr, 0, &sig_size,
                              NCRYPT_SILENT_FLAG | BCRYPT_PAD_PKCS1))) {
      return absl::nullopt;
    }

    std::vector<uint8_t> sig(sig_size);
    if (FAILED(NCryptSignHash(key_.get(), &padding_info, digest.data(),
                              digest.size(), sig.data(), sig.size(), &sig_size,
                              NCRYPT_SILENT_FLAG | BCRYPT_PAD_PKCS1))) {
      return absl::nullopt;
    }
    CHECK_EQ(sig.size(), sig_size);

    return sig;
  }

 private:
  ScopedProvider provider_;
  ScopedKey key_;
  const std::vector<uint8_t> wrapped_;
  const std::vector<uint8_t> spki_;
};

// UnexportableKeyProviderWin uses NCrypt and the Platform Crypto
// Provider to expose TPM-backed keys on Windows.
class UnexportableKeyProviderWin : public UnexportableKeyProvider {
 public:
  ~UnexportableKeyProviderWin() override = default;

  absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
      base::span<const SignatureVerifier::SignatureAlgorithm>
          acceptable_algorithms) override {
    ScopedProvider provider;
    if (FAILED(NCryptOpenStorageProvider(
            ScopedProvider::Receiver(provider).get(),
            MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
      // If the operation failed then |provider| doesn't have a valid handle in
      // it and we shouldn't try to free it.
      std::ignore = provider.release();
      return absl::nullopt;
    }

    return GetBestSupported(provider.get(), acceptable_algorithms);
  }

  std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly(
      base::span<const SignatureVerifier::SignatureAlgorithm>
          acceptable_algorithms) override {
    base::ScopedBlockingCall scoped_blocking_call(
        FROM_HERE, base::BlockingType::WILL_BLOCK);

    ScopedProvider provider;
    if (FAILED(NCryptOpenStorageProvider(
            ScopedProvider::Receiver(provider).get(),
            MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
      // If the operation failed when |provider| doesn't have a valid handle in
      // it and we shouldn't try to free it.
      std::ignore = provider.release();
      return nullptr;
    }

    absl::optional<SignatureVerifier::SignatureAlgorithm> algo =
        GetBestSupported(provider.get(), acceptable_algorithms);
    if (!algo) {
      return nullptr;
    }

    ScopedKey key;
    // An empty key name stops the key being persisted to disk.
    if (FAILED(NCryptCreatePersistedKey(
            provider.get(), ScopedKey::Receiver(key).get(),
            BCryptAlgorithmFor(*algo).value(), /*pszKeyName=*/nullptr,
            /*dwLegacyKeySpec=*/0, /*dwFlags=*/0))) {
      // If the operation failed then |key| doesn't have a valid handle in it
      // and we shouldn't try and free it.
      std::ignore = key.release();
      return nullptr;
    }

    if (FAILED(NCryptFinalizeKey(key.get(), NCRYPT_SILENT_FLAG))) {
      return nullptr;
    }

    const absl::optional<std::vector<uint8_t>> wrapped_key =
        ExportKey(key.get(), BCRYPT_OPAQUE_KEY_BLOB);
    if (!wrapped_key) {
      return nullptr;
    }

    absl::optional<std::vector<uint8_t>> spki;
    switch (*algo) {
      case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
        spki = GetP256ECDSASPKI(key.get());
        if (!spki) {
          return nullptr;
        }
        return std::make_unique<ECDSAKey>(std::move(provider), std::move(key),
                                          std::move(*wrapped_key),
                                          std::move(spki.value()));
      case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
        spki = GetRSASPKI(key.get());
        if (!spki) {
          return nullptr;
        }
        return std::make_unique<RSAKey>(std::move(provider), std::move(key),
                                        std::move(*wrapped_key),
                                        std::move(spki.value()));
      default:
        return nullptr;
    }
  }

  std::unique_ptr<UnexportableSigningKey> FromWrappedSigningKeySlowly(
      base::span<const uint8_t> wrapped) override {
    base::ScopedBlockingCall scoped_blocking_call(
        FROM_HERE, base::BlockingType::WILL_BLOCK);

    ScopedProvider provider;
    if (FAILED(NCryptOpenStorageProvider(
            ScopedProvider::Receiver(provider).get(),
            MS_PLATFORM_CRYPTO_PROVIDER, /*flags=*/0))) {
      // If the operation failed when |provider| doesn't have a valid handle in
      // it and we shouldn't try to free it.
      std::ignore = provider.release();
      return nullptr;
    }

    ScopedKey key;
    if (FAILED(NCryptImportKey(
            provider.get(), /*hImportKey=*/NULL, BCRYPT_OPAQUE_KEY_BLOB,
            /*pParameterList=*/nullptr, ScopedKey::Receiver(key).get(),
            const_cast<PBYTE>(wrapped.data()), wrapped.size(),
            /*dwFlags=*/NCRYPT_SILENT_FLAG))) {
      // If the operation failed then |key| doesn't have a valid handle in it
      // and we shouldn't try and free it.
      std::ignore = key.release();
      return nullptr;
    }

    const absl::optional<std::vector<uint8_t>> algo_bytes =
        GetKeyProperty(key.get(), NCRYPT_ALGORITHM_PROPERTY);
    if (!algo_bytes) {
      return nullptr;
    }

    // The documentation suggests that |NCRYPT_ALGORITHM_PROPERTY| should return
    // the original algorithm, i.e. |BCRYPT_ECDSA_P256_ALGORITHM| for ECDSA. But
    // it actually returns just "ECDSA" for that case.
    static const wchar_t kECDSA[] = L"ECDSA";
    static const wchar_t kRSA[] = BCRYPT_RSA_ALGORITHM;

    absl::optional<std::vector<uint8_t>> spki;
    if (algo_bytes->size() == sizeof(kECDSA) &&
        memcmp(algo_bytes->data(), kECDSA, sizeof(kECDSA)) == 0) {
      spki = GetP256ECDSASPKI(key.get());
      if (!spki) {
        return nullptr;
      }
      return std::make_unique<ECDSAKey>(
          std::move(provider), std::move(key),
          std::vector<uint8_t>(wrapped.begin(), wrapped.end()),
          std::move(spki.value()));
    } else if (algo_bytes->size() == sizeof(kRSA) &&
               memcmp(algo_bytes->data(), kRSA, sizeof(kRSA)) == 0) {
      spki = GetRSASPKI(key.get());
      if (!spki) {
        return nullptr;
      }
      return std::make_unique<RSAKey>(
          std::move(provider), std::move(key),
          std::vector<uint8_t>(wrapped.begin(), wrapped.end()),
          std::move(spki.value()));
    }

    return nullptr;
  }
};

}  // namespace

std::unique_ptr<UnexportableKeyProvider> GetUnexportableKeyProviderWin() {
  return std::make_unique<UnexportableKeyProviderWin>();
}

}  // namespace crypto
