/*
 *  Copyright 2004 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/openssl_certificate.h"

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

#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <time.h>

#include <memory>

#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_identity.h"
#include "rtc_base/openssl_utility.h"

namespace rtc {
namespace {

// Random bits for certificate serial number
static const int SERIAL_RAND_BITS = 64;

#if !defined(NDEBUG)
// Print a certificate to the log, for debugging.
static void PrintCert(X509* x509) {
  BIO* temp_memory_bio = BIO_new(BIO_s_mem());
  if (!temp_memory_bio) {
    RTC_DLOG_F(LS_ERROR) << "Failed to allocate temporary memory bio";
    return;
  }
  X509_print_ex(temp_memory_bio, x509, XN_FLAG_SEP_CPLUS_SPC, 0);
  BIO_write(temp_memory_bio, "\0", 1);
  char* buffer;
  BIO_get_mem_data(temp_memory_bio, &buffer);
  RTC_DLOG(LS_VERBOSE) << buffer;
  BIO_free(temp_memory_bio);
}
#endif

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

  ASN1_INTEGER* asn1_serial_number = nullptr;
  std::unique_ptr<BIGNUM, decltype(&::BN_free)> serial_number{nullptr,
                                                              ::BN_free};
  std::unique_ptr<X509, decltype(&::X509_free)> x509{nullptr, ::X509_free};
  std::unique_ptr<X509_NAME, decltype(&::X509_NAME_free)> name{
      nullptr, ::X509_NAME_free};
  time_t epoch_off = 0;  // Time offset since epoch.
  x509.reset(X509_new());
  if (x509 == nullptr) {
    return nullptr;
  }
  if (!X509_set_pubkey(x509.get(), pkey)) {
    return nullptr;
  }
  // serial number - temporary reference to serial number inside x509 struct
  serial_number.reset(BN_new());
  if (serial_number == nullptr ||
      !BN_pseudo_rand(serial_number.get(), SERIAL_RAND_BITS, 0, 0) ||
      (asn1_serial_number = X509_get_serialNumber(x509.get())) == nullptr ||
      !BN_to_ASN1_INTEGER(serial_number.get(), asn1_serial_number)) {
    return nullptr;
  }
  // Set version to X509.V3
  if (!X509_set_version(x509.get(), 2L)) {
    return nullptr;
  }

  // There are a lot of possible components for the name entries. In
  // our P2P SSL mode however, the certificates are pre-exchanged
  // (through the secure XMPP channel), and so the certificate
  // identification is arbitrary. It can't be empty, so we set some
  // arbitrary common_name. Note that this certificate goes out in
  // clear during SSL negotiation, so there may be a privacy issue in
  // putting anything recognizable here.
  name.reset(X509_NAME_new());
  if (name == nullptr ||
      !X509_NAME_add_entry_by_NID(name.get(), NID_commonName, MBSTRING_UTF8,
                                  (unsigned char*)params.common_name.c_str(),
                                  -1, -1, 0) ||
      !X509_set_subject_name(x509.get(), name.get()) ||
      !X509_set_issuer_name(x509.get(), name.get())) {
    return nullptr;
  }
  if (!X509_time_adj(X509_get_notBefore(x509.get()), params.not_before,
                     &epoch_off) ||
      !X509_time_adj(X509_get_notAfter(x509.get()), params.not_after,
                     &epoch_off)) {
    return nullptr;
  }
  if (!X509_sign(x509.get(), pkey, EVP_sha256())) {
    return nullptr;
  }

  RTC_LOG(LS_INFO) << "Returning certificate";
  return x509.release();
}

}  // namespace

OpenSSLCertificate::OpenSSLCertificate(X509* x509) : x509_(x509) {
  RTC_DCHECK(x509_ != nullptr);
  X509_up_ref(x509_);
}

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

std::unique_ptr<OpenSSLCertificate> OpenSSLCertificate::FromPEMString(
    absl::string_view pem_string) {
  BIO* bio = BIO_new_mem_buf(const_cast<char*>(pem_string.data()), -1);
  if (!bio) {
    return nullptr;
  }

  BIO_set_mem_eof_return(bio, 0);
  X509* x509 =
      PEM_read_bio_X509(bio, nullptr, nullptr, const_cast<char*>("\0"));
  BIO_free(bio);  // Frees the BIO, but not the pointed-to string.

  if (!x509) {
    return nullptr;
  }
  auto ret = std::make_unique<OpenSSLCertificate>(x509);
  X509_free(x509);
  return ret;
}

// NOTE: This implementation only functions correctly after InitializeSSL
// and before CleanupSSL.
bool OpenSSLCertificate::GetSignatureDigestAlgorithm(
    std::string* algorithm) const {
  int nid = X509_get_signature_nid(x509_);
  switch (nid) {
    case NID_md5WithRSA:
    case NID_md5WithRSAEncryption:
      *algorithm = DIGEST_MD5;
      break;
    case NID_ecdsa_with_SHA1:
    case NID_dsaWithSHA1:
    case NID_dsaWithSHA1_2:
    case NID_sha1WithRSA:
    case NID_sha1WithRSAEncryption:
      *algorithm = DIGEST_SHA_1;
      break;
    case NID_ecdsa_with_SHA224:
    case NID_sha224WithRSAEncryption:
    case NID_dsa_with_SHA224:
      *algorithm = DIGEST_SHA_224;
      break;
    case NID_ecdsa_with_SHA256:
    case NID_sha256WithRSAEncryption:
    case NID_dsa_with_SHA256:
      *algorithm = DIGEST_SHA_256;
      break;
    case NID_ecdsa_with_SHA384:
    case NID_sha384WithRSAEncryption:
      *algorithm = DIGEST_SHA_384;
      break;
    case NID_ecdsa_with_SHA512:
    case NID_sha512WithRSAEncryption:
      *algorithm = DIGEST_SHA_512;
      break;
    default:
      // Unknown algorithm.  There are several unhandled options that are less
      // common and more complex.
      RTC_LOG(LS_ERROR) << "Unknown signature algorithm NID: " << nid;
      algorithm->clear();
      return false;
  }
  return true;
}

bool OpenSSLCertificate::ComputeDigest(absl::string_view algorithm,
                                       unsigned char* digest,
                                       size_t size,
                                       size_t* length) const {
  return ComputeDigest(x509_, algorithm, digest, size, length);
}

bool OpenSSLCertificate::ComputeDigest(const X509* x509,
                                       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;
  }
  X509_digest(x509, md, digest, &n);
  *length = n;
  return true;
}

OpenSSLCertificate::~OpenSSLCertificate() {
  X509_free(x509_);
}

std::unique_ptr<SSLCertificate> OpenSSLCertificate::Clone() const {
  return std::make_unique<OpenSSLCertificate>(x509_);
}

std::string OpenSSLCertificate::ToPEMString() const {
  BIO* bio = BIO_new(BIO_s_mem());
  RTC_CHECK(bio);
  RTC_CHECK(PEM_write_bio_X509(bio, x509_));
  BIO_write(bio, "\0", 1);
  char* buffer;
  BIO_get_mem_data(bio, &buffer);
  std::string ret(buffer);
  BIO_free(bio);
  return ret;
}

void OpenSSLCertificate::ToDER(Buffer* der_buffer) const {
  // In case of failure, make sure to leave the buffer empty.
  der_buffer->SetSize(0);
  // Calculates the DER representation of the certificate, from scratch.
  BIO* bio = BIO_new(BIO_s_mem());
  RTC_CHECK(bio);
  RTC_CHECK(i2d_X509_bio(bio, x509_));
  char* data = nullptr;
  size_t length = BIO_get_mem_data(bio, &data);
  der_buffer->SetData(data, length);
  BIO_free(bio);
}

bool OpenSSLCertificate::operator==(const OpenSSLCertificate& other) const {
  return X509_cmp(x509_, other.x509_) == 0;
}

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

int64_t OpenSSLCertificate::CertificateExpirationTime() const {
  ASN1_TIME* expire_time = X509_get_notAfter(x509_);
  bool long_format;
  if (expire_time->type == V_ASN1_UTCTIME) {
    long_format = false;
  } else if (expire_time->type == V_ASN1_GENERALIZEDTIME) {
    long_format = true;
  } else {
    return -1;
  }
  return ASN1TimeToSec(expire_time->data, expire_time->length, long_format);
}

}  // namespace rtc
