// Copyright 2015 The Chromium OS 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 "webservd/utils.h"

#include <sys/socket.h>

#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>

namespace webservd {

namespace {

// Returns the current date/time. This is used for TLS certificate validation
// very early in process start when the system clock might not be adjusted
// yet on devices that don't have a real-time clock. So, try to get the system
// time and if it is earlier than the build date of this executable, use
// the build date instead as a lower limit to the date/time.
// See http://b/23897170 for more details.
base::Time GetTimeNow() {
  base::Time now = base::Time::Now();

  base::File::Info info;
  base::FilePath exe_path;
  if (!base::ReadSymbolicLink(base::FilePath{"/proc/self/exe"}, &exe_path) ||
      !base::GetFileInfo(exe_path, &info) || info.creation_time < now) {
    return now;
  }

  LOG(WARNING) << "Current time (" << now
               << ") is earlier than the application build time. Using "
               << info.creation_time << " instead!";
  return info.creation_time;
}

}  // anonymous namespace

X509Ptr CreateCertificate(int serial_number,
                          const base::TimeDelta& cert_expiration,
                          const std::string& common_name) {
  auto cert = X509Ptr{X509_new(), X509_free};
  CHECK(cert.get());
  X509_set_version(cert.get(), 2);  // Using X.509 v3 certificate...

  // Set certificate properties...
  ASN1_INTEGER* sn = X509_get_serialNumber(cert.get());
  ASN1_INTEGER_set(sn, serial_number);
  time_t current_time = GetTimeNow().ToTimeT();
  X509_time_adj(X509_get_notBefore(cert.get()), 0, &current_time);
  X509_time_adj(X509_get_notAfter(cert.get()), cert_expiration.InSeconds(),
                &current_time);

  // The issuer is the same as the subject, since this cert is self-signed.
  X509_NAME* name = X509_get_subject_name(cert.get());
  if (!common_name.empty()) {
    X509_NAME_add_entry_by_txt(
        name, "CN", MBSTRING_UTF8,
        reinterpret_cast<const unsigned char*>(common_name.c_str()),
        common_name.length(), -1, 0);
  }
  X509_set_issuer_name(cert.get(), name);
  return cert;
}

std::unique_ptr<RSA, void (*)(RSA*)> GenerateRSAKeyPair(int key_length_bits) {
  // Create RSA key pair.
  auto rsa_key_pair = std::unique_ptr<RSA, void (*)(RSA*)>{RSA_new(), RSA_free};
  CHECK(rsa_key_pair.get());
  auto big_num = std::unique_ptr<BIGNUM, void (*)(BIGNUM*)>{BN_new(), BN_free};
  CHECK(big_num.get());
  CHECK(BN_set_word(big_num.get(), 65537));
  CHECK(RSA_generate_key_ex(rsa_key_pair.get(), key_length_bits, big_num.get(),
                            nullptr));
  return rsa_key_pair;
}

brillo::SecureBlob StoreRSAPrivateKey(RSA* rsa_key_pair) {
  auto bio =
      std::unique_ptr<BIO, void (*)(BIO*)>{BIO_new(BIO_s_mem()), BIO_vfree};
  CHECK(bio);
  CHECK(PEM_write_bio_RSAPrivateKey(bio.get(), rsa_key_pair, nullptr, nullptr,
                                    0, nullptr, nullptr));
  uint8_t* buffer = nullptr;
  size_t size = BIO_get_mem_data(bio.get(), reinterpret_cast<char**>(&buffer));
  CHECK_GT(size, 0u);
  CHECK(buffer);
  brillo::SecureBlob key_blob(buffer, buffer + size);
  brillo::SecureClear(buffer, size);
  return key_blob;
}

bool ValidateRSAPrivateKey(const brillo::SecureBlob& key) {
  std::unique_ptr<BIO, void (*)(BIO*)> bio{
      BIO_new_mem_buf(const_cast<uint8_t*>(key.data()), key.size()), BIO_vfree};
  std::unique_ptr<RSA, void (*)(RSA*)> rsa_key{
      PEM_read_bio_RSAPrivateKey(bio.get(), nullptr, nullptr, nullptr),
      RSA_free};
  return rsa_key.get() != nullptr;
}

brillo::Blob StoreCertificate(X509* cert) {
  auto bio =
      std::unique_ptr<BIO, void (*)(BIO*)>{BIO_new(BIO_s_mem()), BIO_vfree};
  CHECK(bio);
  CHECK(PEM_write_bio_X509(bio.get(), cert));
  uint8_t* buffer = nullptr;
  size_t size = BIO_get_mem_data(bio.get(), reinterpret_cast<char**>(&buffer));
  CHECK_GT(size, 0u);
  CHECK(buffer);
  return brillo::Blob(buffer, buffer + size);
}

bool StoreCertificate(X509* cert, const base::FilePath& file) {
  std::unique_ptr<BIO, void (*)(BIO*)> bio{
      BIO_new_file(file.value().c_str(), "w"), BIO_vfree};
  return bio && PEM_write_bio_X509(bio.get(), cert) != 0;
}

X509Ptr LoadAndValidateCertificate(const base::FilePath& file) {
  X509Ptr cert{nullptr, X509_free};
  std::unique_ptr<BIO, void (*)(BIO*)> bio{
      BIO_new_file(file.value().c_str(), "r"), BIO_vfree};
  if (!bio)
    return cert;
  LOG(INFO) << "Loading certificate from " << file.value();
  cert.reset(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
  if (cert) {
    // Regenerate certificate 30 days before it expires.
    time_t deadline = (GetTimeNow() + base::TimeDelta::FromDays(30)).ToTimeT();
    if (X509_cmp_time(X509_get_notAfter(cert.get()), &deadline) < 0) {
      LOG(WARNING) << "Certificate is expiring soon. Regenerating new one.";
      cert.reset();
    }
  }
  return cert;
}

// Same as openssl x509 -fingerprint -sha256.
brillo::Blob GetSha256Fingerprint(X509* cert) {
  brillo::Blob fingerprint(256 / 8);
  uint32_t len = 0;
  CHECK(X509_digest(cert, EVP_sha256(), fingerprint.data(), &len));
  CHECK_EQ(len, fingerprint.size());
  return fingerprint;
}

int CreateNetworkInterfaceSocket(const std::string& if_name) {
  // The following is basically the steps libmicrohttpd normally takes
  // when creating a new listening socket and binding it to a port.
  int socket_fd = socket(PF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
  if (socket_fd < 0 && errno == EINVAL)
    socket_fd = socket(PF_INET6, SOCK_STREAM, 0);
  if (socket_fd < 0) {
    PLOG(ERROR) << "Unable to create a listening socket";
    return -1;
  }

  // Now, specify that we want this socket to bind only to a particular
  // network interface. Note, this call requires root privileges, so this
  // should be done before the privileges are dropped.
  if (setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, if_name.c_str(),
                 if_name.size()) < 0) {
    PLOG(WARNING) << "Failed to bind socket (SO_BINDTODEVICE) to " << if_name;
    close(socket_fd);
    return -1;
  }
  return socket_fd;
}

}  // namespace webservd
