/*
 *  Copyright 2020 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/boringssl_certificate.h"

#include "absl/strings/string_view.h"

#if defined(WEBRTC_WIN)
// Must be included first before openssl headers.
#include "rtc_base/win32.h"  // NOLINT
#endif                       // WEBRTC_WIN

#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/pool.h>
#include <openssl/rand.h>
#include <time.h>

#include <cstring>
#include <memory>
#include <utility>
#include <vector>

#include "rtc_base/checks.h"
#include "rtc_base/helpers.h"
#include "rtc_base/logging.h"
#include "rtc_base/message_digest.h"
#include "rtc_base/openssl_digest.h"
#include "rtc_base/openssl_key_pair.h"
#include "rtc_base/openssl_utility.h"

namespace rtc {
namespace {

// List of OIDs of signature algorithms accepted by WebRTC.
// Taken from openssl/nid.h.
static const uint8_t kMD5WithRSA[] = {0x2b, 0x0e, 0x03, 0x02, 0x03};
static const uint8_t kMD5WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                                0x0d, 0x01, 0x01, 0x04};
static const uint8_t kECDSAWithSHA1[] = {0x2a, 0x86, 0x48, 0xce,
                                         0x3d, 0x04, 0x01};
static const uint8_t kDSAWithSHA1[] = {0x2a, 0x86, 0x48, 0xce,
                                       0x38, 0x04, 0x03};
static const uint8_t kDSAWithSHA1_2[] = {0x2b, 0x0e, 0x03, 0x02, 0x1b};
static const uint8_t kSHA1WithRSA[] = {0x2b, 0x0e, 0x03, 0x02, 0x1d};
static const uint8_t kSHA1WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                                 0x0d, 0x01, 0x01, 0x05};
static const uint8_t kECDSAWithSHA224[] = {0x2a, 0x86, 0x48, 0xce,
                                           0x3d, 0x04, 0x03, 0x01};
static const uint8_t kSHA224WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                                   0x0d, 0x01, 0x01, 0x0e};
static const uint8_t kDSAWithSHA224[] = {0x60, 0x86, 0x48, 0x01, 0x65,
                                         0x03, 0x04, 0x03, 0x01};
static const uint8_t kECDSAWithSHA256[] = {0x2a, 0x86, 0x48, 0xce,
                                           0x3d, 0x04, 0x03, 0x02};
static const uint8_t kSHA256WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                                   0x0d, 0x01, 0x01, 0x0b};
static const uint8_t kDSAWithSHA256[] = {0x60, 0x86, 0x48, 0x01, 0x65,
                                         0x03, 0x04, 0x03, 0x02};
static const uint8_t kECDSAWithSHA384[] = {0x2a, 0x86, 0x48, 0xce,
                                           0x3d, 0x04, 0x03, 0x03};
static const uint8_t kSHA384WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                                   0x0d, 0x01, 0x01, 0x0c};
static const uint8_t kECDSAWithSHA512[] = {0x2a, 0x86, 0x48, 0xce,
                                           0x3d, 0x04, 0x03, 0x04};
static const uint8_t kSHA512WithRSAEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
                                                   0x0d, 0x01, 0x01, 0x0d};

#if !defined(NDEBUG)
// Print a certificate to the log, for debugging.
static void PrintCert(BoringSSLCertificate* cert) {
  // Since we're using CRYPTO_BUFFER, we can't use X509_print_ex, so we'll just
  // print the PEM string.
  RTC_DLOG(LS_VERBOSE) << "PEM representation of certificate:\n"
                       << cert->ToPEMString();
}
#endif

bool AddSHA256SignatureAlgorithm(CBB* cbb, KeyType key_type) {
  // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
  CBB sequence, oid, params;
  if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT)) {
    return false;
  }

  switch (key_type) {
    case KT_RSA:
      if (!CBB_add_bytes(&oid, kSHA256WithRSAEncryption,
                         sizeof(kSHA256WithRSAEncryption)) ||
          !CBB_add_asn1(&sequence, &params, CBS_ASN1_NULL)) {
        return false;
      }
      break;
    case KT_ECDSA:
      if (!CBB_add_bytes(&oid, kECDSAWithSHA256, sizeof(kECDSAWithSHA256))) {
        return false;
      }
      break;
    default:
      RTC_DCHECK_NOTREACHED();
      return false;
  }
  if (!CBB_flush(cbb)) {
    return false;
  }
  return true;
}

// Adds an X.509 Common Name to `cbb`.
bool AddCommonName(CBB* cbb, absl::string_view common_name) {
  // See RFC 4519.
  static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};

  if (common_name.empty()) {
    RTC_LOG(LS_ERROR) << "Common name cannot be empty.";
    return false;
  }

  // See RFC 5280, section 4.1.2.4.
  CBB rdns;
  if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
    return false;
  }

  CBB rdn, attr, type, value;
  if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
      !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
      !CBB_add_bytes(&type, kCommonName, sizeof(kCommonName)) ||
      !CBB_add_asn1(&attr, &value, CBS_ASN1_UTF8STRING) ||
      !CBB_add_bytes(&value,
                     reinterpret_cast<const uint8_t*>(common_name.data()),
                     common_name.size()) ||
      !CBB_flush(cbb)) {
    return false;
  }

  return true;
}

bool AddTime(CBB* cbb, time_t time) {
  bssl::UniquePtr<ASN1_TIME> asn1_time(ASN1_TIME_new());
  if (!asn1_time) {
    return false;
  }

  if (!ASN1_TIME_set(asn1_time.get(), time)) {
    return false;
  }

  unsigned tag;
  switch (asn1_time->type) {
    case V_ASN1_UTCTIME:
      tag = CBS_ASN1_UTCTIME;
      break;
    case V_ASN1_GENERALIZEDTIME:
      tag = CBS_ASN1_GENERALIZEDTIME;
      break;
    default:
      return false;
  }

  CBB child;
  if (!CBB_add_asn1(cbb, &child, tag) ||
      !CBB_add_bytes(&child, asn1_time->data, asn1_time->length) ||
      !CBB_flush(cbb)) {
    return false;
  }

  return true;
}

// Generate a self-signed certificate, with the public key from the
// given key pair. Caller is responsible for freeing the returned object.
static bssl::UniquePtr<CRYPTO_BUFFER> MakeCertificate(
    EVP_PKEY* pkey,
    const SSLIdentityParams& params) {
  RTC_LOG(LS_INFO) << "Making certificate for " << params.common_name;

  // See RFC 5280, section 4.1. First, construct the TBSCertificate.
  bssl::ScopedCBB cbb;
  CBB tbs_cert, version, validity;
  uint8_t* tbs_cert_bytes;
  size_t tbs_cert_len;
  uint64_t serial_number;
  if (!CBB_init(cbb.get(), 64) ||
      !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
      !CBB_add_asn1(&tbs_cert, &version,
                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
      !CBB_add_asn1_uint64(&version, 2) ||
      !RAND_bytes(reinterpret_cast<uint8_t*>(&serial_number),
                  sizeof(serial_number)) ||
      !CBB_add_asn1_uint64(&tbs_cert, serial_number) ||
      !AddSHA256SignatureAlgorithm(&tbs_cert, params.key_params.type()) ||
      !AddCommonName(&tbs_cert, params.common_name) ||  // issuer
      !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
      !AddTime(&validity, params.not_before) ||
      !AddTime(&validity, params.not_after) ||
      !AddCommonName(&tbs_cert, params.common_name) ||  // subject
      !EVP_marshal_public_key(&tbs_cert, pkey) ||       // subjectPublicKeyInfo
      !CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len)) {
    return nullptr;
  }

  bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);

  // Sign the TBSCertificate and write the entire certificate.
  CBB cert, signature;
  bssl::ScopedEVP_MD_CTX ctx;
  uint8_t* sig_out;
  size_t sig_len;
  uint8_t* cert_bytes;
  size_t cert_len;
  if (!CBB_init(cbb.get(), tbs_cert_len) ||
      !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
      !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
      !AddSHA256SignatureAlgorithm(&cert, params.key_params.type()) ||
      !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
      !CBB_add_u8(&signature, 0 /* no unused bits */) ||
      !EVP_DigestSignInit(ctx.get(), nullptr, EVP_sha256(), nullptr, pkey) ||
      // Compute the maximum signature length.
      !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
                      tbs_cert_len) ||
      !CBB_reserve(&signature, &sig_out, sig_len) ||
      // Actually sign the TBSCertificate.
      !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
                      tbs_cert_len) ||
      !CBB_did_write(&signature, sig_len) ||
      !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
    return nullptr;
  }
  bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);

  RTC_LOG(LS_INFO) << "Returning certificate";
  return bssl::UniquePtr<CRYPTO_BUFFER>(
      CRYPTO_BUFFER_new(cert_bytes, cert_len, openssl::GetBufferPool()));
}

}  // namespace

BoringSSLCertificate::BoringSSLCertificate(
    bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer)
    : cert_buffer_(std::move(cert_buffer)) {
  RTC_DCHECK(cert_buffer_ != nullptr);
}

std::unique_ptr<BoringSSLCertificate> BoringSSLCertificate::Generate(
    OpenSSLKeyPair* key_pair,
    const SSLIdentityParams& params) {
  SSLIdentityParams actual_params(params);
  if (actual_params.common_name.empty()) {
    // Use a random string, arbitrarily 8 chars long.
    actual_params.common_name = CreateRandomString(8);
  }
  bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer =
      MakeCertificate(key_pair->pkey(), actual_params);
  if (!cert_buffer) {
    openssl::LogSSLErrors("Generating certificate");
    return nullptr;
  }
  auto ret = std::make_unique<BoringSSLCertificate>(std::move(cert_buffer));
#if !defined(NDEBUG)
  PrintCert(ret.get());
#endif
  return ret;
}

std::unique_ptr<BoringSSLCertificate> BoringSSLCertificate::FromPEMString(
    absl::string_view pem_string) {
  std::string der;
  if (!SSLIdentity::PemToDer(kPemTypeCertificate, pem_string, &der)) {
    return nullptr;
  }
  bssl::UniquePtr<CRYPTO_BUFFER> cert_buffer(
      CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(der.c_str()),
                        der.length(), openssl::GetBufferPool()));
  if (!cert_buffer) {
    return nullptr;
  }
  return std::make_unique<BoringSSLCertificate>(std::move(cert_buffer));
}

#define OID_MATCHES(oid, oid_other)      \
  (CBS_len(&oid) == sizeof(oid_other) && \
   0 == memcmp(CBS_data(&oid), oid_other, sizeof(oid_other)))

bool BoringSSLCertificate::GetSignatureDigestAlgorithm(
    std::string* algorithm) const {
  CBS oid;
  if (!openssl::ParseCertificate(cert_buffer_.get(), &oid, nullptr)) {
    RTC_LOG(LS_ERROR) << "Failed to parse certificate.";
    return false;
  }
  if (OID_MATCHES(oid, kMD5WithRSA) ||
      OID_MATCHES(oid, kMD5WithRSAEncryption)) {
    *algorithm = DIGEST_MD5;
    return true;
  }
  if (OID_MATCHES(oid, kECDSAWithSHA1) || OID_MATCHES(oid, kDSAWithSHA1) ||
      OID_MATCHES(oid, kDSAWithSHA1_2) || OID_MATCHES(oid, kSHA1WithRSA) ||
      OID_MATCHES(oid, kSHA1WithRSAEncryption)) {
    *algorithm = DIGEST_SHA_1;
    return true;
  }
  if (OID_MATCHES(oid, kECDSAWithSHA224) ||
      OID_MATCHES(oid, kSHA224WithRSAEncryption) ||
      OID_MATCHES(oid, kDSAWithSHA224)) {
    *algorithm = DIGEST_SHA_224;
    return true;
  }
  if (OID_MATCHES(oid, kECDSAWithSHA256) ||
      OID_MATCHES(oid, kSHA256WithRSAEncryption) ||
      OID_MATCHES(oid, kDSAWithSHA256)) {
    *algorithm = DIGEST_SHA_256;
    return true;
  }
  if (OID_MATCHES(oid, kECDSAWithSHA384) ||
      OID_MATCHES(oid, kSHA384WithRSAEncryption)) {
    *algorithm = DIGEST_SHA_384;
    return true;
  }
  if (OID_MATCHES(oid, kECDSAWithSHA512) ||
      OID_MATCHES(oid, kSHA512WithRSAEncryption)) {
    *algorithm = DIGEST_SHA_512;
    return true;
  }
  // Unknown algorithm.  There are several unhandled options that are less
  // common and more complex.
  RTC_LOG(LS_ERROR) << "Unknown signature algorithm.";
  algorithm->clear();
  return false;
}

bool BoringSSLCertificate::ComputeDigest(absl::string_view algorithm,
                                         unsigned char* digest,
                                         size_t size,
                                         size_t* length) const {
  return ComputeDigest(cert_buffer_.get(), algorithm, digest, size, length);
}

bool BoringSSLCertificate::ComputeDigest(const CRYPTO_BUFFER* cert_buffer,
                                         absl::string_view algorithm,
                                         unsigned char* digest,
                                         size_t size,
                                         size_t* length) {
  const EVP_MD* md = nullptr;
  unsigned int n = 0;
  if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) {
    return false;
  }
  if (size < static_cast<size_t>(EVP_MD_size(md))) {
    return false;
  }
  if (!EVP_Digest(CRYPTO_BUFFER_data(cert_buffer),
                  CRYPTO_BUFFER_len(cert_buffer), digest, &n, md, nullptr)) {
    return false;
  }
  *length = n;
  return true;
}

BoringSSLCertificate::~BoringSSLCertificate() {}

std::unique_ptr<SSLCertificate> BoringSSLCertificate::Clone() const {
  return std::make_unique<BoringSSLCertificate>(
      bssl::UpRef(cert_buffer_.get()));
}

std::string BoringSSLCertificate::ToPEMString() const {
  return SSLIdentity::DerToPem(kPemTypeCertificate,
                               CRYPTO_BUFFER_data(cert_buffer_.get()),
                               CRYPTO_BUFFER_len(cert_buffer_.get()));
}

void BoringSSLCertificate::ToDER(Buffer* der_buffer) const {
  der_buffer->SetData(CRYPTO_BUFFER_data(cert_buffer_.get()),
                      CRYPTO_BUFFER_len(cert_buffer_.get()));
}

bool BoringSSLCertificate::operator==(const BoringSSLCertificate& other) const {
  return CRYPTO_BUFFER_len(cert_buffer_.get()) ==
             CRYPTO_BUFFER_len(other.cert_buffer_.get()) &&
         0 == memcmp(CRYPTO_BUFFER_data(cert_buffer_.get()),
                     CRYPTO_BUFFER_data(other.cert_buffer_.get()),
                     CRYPTO_BUFFER_len(cert_buffer_.get()));
}

bool BoringSSLCertificate::operator!=(const BoringSSLCertificate& other) const {
  return !(*this == other);
}

int64_t BoringSSLCertificate::CertificateExpirationTime() const {
  int64_t ret;
  if (!openssl::ParseCertificate(cert_buffer_.get(), nullptr, &ret)) {
    RTC_LOG(LS_ERROR) << "Failed to parse certificate.";
    return -1;
  }
  return ret;
}

}  // namespace rtc
