/*
 *  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"

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

#include <cstdint>
#include <ctime>
#include <memory>
#include <string>

#include "absl/strings/string_view.h"
#include "rtc_base/buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/crypto_random.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"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"

namespace webrtc {
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_DCHECK(pkey != nullptr);
  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.data(), -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,
                                       Buffer& digest) const {
  RTC_DCHECK_GT(digest.capacity(), 0);
  const EVP_MD* md = nullptr;
  unsigned int n = 0;
  if (!OpenSSLDigest::GetDigestEVP(algorithm, &md)) {
    return false;
  }
  if (digest.capacity() < static_cast<size_t>(EVP_MD_size(md))) {
    return false;
  }
  X509_digest(x509_, md, digest.data(), &n);
  digest.SetSize(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 webrtc
