#include "config.h"

#include "certificate.hpp"

#include "certs_manager.hpp"
#include "x509_utils.hpp"

#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/obj_mac.h>
#include <openssl/objects.h>
#include <openssl/opensslv.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>

#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/lg2.hpp>
#include <watch.hpp>
#include <xyz/openbmc_project/Certs/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <exception>
#include <filesystem>
#include <fstream>
#include <map>
#include <utility>
#include <vector>

namespace phosphor::certs
{

namespace
{
namespace fs = std::filesystem;
using ::phosphor::logging::elog;
using InvalidCertificateError =
    ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
using ::phosphor::logging::xyz::openbmc_project::Certs::InvalidCertificate;
using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;

// RAII support for openSSL functions.
using BIOMemPtr = std::unique_ptr<BIO, decltype(&::BIO_free)>;
using X509StorePtr = std::unique_ptr<X509_STORE, decltype(&::X509_STORE_free)>;
using ASN1TimePtr = std::unique_ptr<ASN1_TIME, decltype(&ASN1_STRING_free)>;
using EVPPkeyPtr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using BufMemPtr = std::unique_ptr<BUF_MEM, decltype(&::BUF_MEM_free)>;

// Refer to schema 2018.3
// http://redfish.dmtf.org/schemas/v1/Certificate.json#/definitions/KeyUsage for
// supported KeyUsage types in redfish
// Refer to
// https://github.com/openssl/openssl/blob/master/include/openssl/x509v3.h for
// key usage bit fields
std::map<uint8_t, std::string> keyUsageToRfStr = {
    {KU_DIGITAL_SIGNATURE, "DigitalSignature"},
    {KU_NON_REPUDIATION, "NonRepudiation"},
    {KU_KEY_ENCIPHERMENT, "KeyEncipherment"},
    {KU_DATA_ENCIPHERMENT, "DataEncipherment"},
    {KU_KEY_AGREEMENT, "KeyAgreement"},
    {KU_KEY_CERT_SIGN, "KeyCertSign"},
    {KU_CRL_SIGN, "CRLSigning"},
    {KU_ENCIPHER_ONLY, "EncipherOnly"},
    {KU_DECIPHER_ONLY, "DecipherOnly"}};

// Refer to schema 2018.3
// http://redfish.dmtf.org/schemas/v1/Certificate.json#/definitions/KeyUsage for
// supported Extended KeyUsage types in redfish
std::map<uint8_t, std::string> extendedKeyUsageToRfStr = {
    {NID_server_auth, "ServerAuthentication"},
    {NID_client_auth, "ClientAuthentication"},
    {NID_email_protect, "EmailProtection"},
    {NID_OCSP_sign, "OCSPSigning"},
    {NID_ad_timeStamping, "Timestamping"},
    {NID_code_sign, "CodeSigning"}};

/**
 * @brief Dumps the PEM encoded certificate to installFilePath
 *
 * @param[in] pem - PEM encoded X509 certificate buffer.
 * @param[in] certFilePath - Path to the destination file.
 *
 * @return void
 */

void dumpCertificate(const std::string& pem, const std::string& certFilePath)
{
    std::ofstream outputCertFileStream;

    outputCertFileStream.exceptions(
        std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit);

    try
    {
        outputCertFileStream.open(certFilePath, std::ios::out);
        outputCertFileStream << pem << "\n" << std::flush;
        outputCertFileStream.close();
    }
    catch (const std::exception& e)
    {
        lg2::error(
            "Failed to dump certificate, ERR:{ERR}, SRC_PEM:{SRC_PEM}, DST:{DST}",
            "ERR", e, "SRC_PEM", pem, "DST", certFilePath);
        elog<InternalFailure>();
    }
}
} // namespace

void Certificate::copyCertificate(const std::string& certSrcFilePath,
                                  const std::string& certFilePath)
{
    // Copy the certificate to the installation path
    // During bootup will be parsing existing file so no need to
    // copy it.
    if (certSrcFilePath != certFilePath)
    {
        std::ifstream inputCertFileStream;
        std::ofstream outputCertFileStream;
        inputCertFileStream.exceptions(std::ifstream::failbit |
                                       std::ifstream::badbit |
                                       std::ifstream::eofbit);
        outputCertFileStream.exceptions(std::ofstream::failbit |
                                        std::ofstream::badbit |
                                        std::ofstream::eofbit);
        try
        {
            inputCertFileStream.open(certSrcFilePath);
            outputCertFileStream.open(certFilePath, std::ios::out);
            outputCertFileStream << inputCertFileStream.rdbuf() << std::flush;
            inputCertFileStream.close();
            outputCertFileStream.close();
        }
        catch (const std::exception& e)
        {
            lg2::error(
                "Failed to copy certificate, ERR:{ERR}, SRC:{SRC}, DST:{DST}",
                "ERR", e, "SRC", certSrcFilePath, "DST", certFilePath);
            elog<InternalFailure>();
        }
    }
}

std::string
    Certificate::generateUniqueFilePath(const std::string& directoryPath)
{
    char* filePath = tempnam(directoryPath.c_str(), nullptr);
    if (filePath == nullptr)
    {
        lg2::error(
            "Error occurred while creating random certificate file path, DIR:{DIR}",
            "DIR", directoryPath);
        elog<InternalFailure>();
    }
    std::string filePathStr(filePath);
    free(filePath);
    return filePathStr;
}

std::string Certificate::generateAuthCertFileX509Path(
    const std::string& certSrcFilePath, const std::string& certDstDirPath)
{
    const internal::X509Ptr cert = loadCert(certSrcFilePath);
    unsigned long hash = X509_subject_name_hash(cert.get());
    static constexpr auto certHashLength = 9;
    char hashBuf[certHashLength];

    snprintf(hashBuf, certHashLength, "%08lx", hash);

    const std::string certHash(hashBuf);
    for (size_t i = 0; i < maxNumAuthorityCertificates; ++i)
    {
        const std::string certDstFileX509Path =
            certDstDirPath + "/" + certHash + "." + std::to_string(i);
        if (!fs::exists(certDstFileX509Path))
        {
            return certDstFileX509Path;
        }
    }

    lg2::error("Authority certificate x509 file path already used, DIR:{DIR}",
               "DIR", certDstDirPath);
    elog<InternalFailure>();
}

std::string
    Certificate::generateAuthCertFilePath(const std::string& certSrcFilePath)
{
    // If there is a certificate file path (which means certificate replacement
    // is doing) use it (do not create new one)
    if (!certFilePath.empty())
    {
        return certFilePath;
    }
    // If source certificate file is located in the certificates directory use
    // it (do not create new one)
    else if (fs::path(certSrcFilePath).parent_path().string() ==
             certInstallPath)
    {
        return certSrcFilePath;
    }
    // Otherwise generate new file name/path
    else
    {
        return generateUniqueFilePath(certInstallPath);
    }
}

std::string
    Certificate::generateCertFilePath(const std::string& certSrcFilePath)
{
    if (certType == CertificateType::authority)
    {
        return generateAuthCertFilePath(certSrcFilePath);
    }
    else
    {
        return certInstallPath;
    }
}

Certificate::Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
                         CertificateType type, const std::string& installPath,
                         const std::string& uploadPath, Watch* watch,
                         Manager& parent, bool restore) :
    internal::CertificateInterface(
        bus, objPath.c_str(),
        internal::CertificateInterface::action::defer_emit),
    objectPath(objPath), certType(type), certInstallPath(installPath),
    certWatch(watch), manager(parent)
{
    auto installHelper = [this](const auto& filePath) {
        if (!compareKeys(filePath))
        {
            elog<InvalidCertificateError>(InvalidCertificate::REASON(
                "Private key does not match the Certificate"));
        };
    };
    typeFuncMap[CertificateType::server] = installHelper;
    typeFuncMap[CertificateType::client] = installHelper;
    typeFuncMap[CertificateType::authority] = [](const std::string&) {};

    auto appendPrivateKey = [this](const std::string& filePath) {
        checkAndAppendPrivateKey(filePath);
    };

    appendKeyMap[CertificateType::server] = appendPrivateKey;
    appendKeyMap[CertificateType::client] = appendPrivateKey;
    appendKeyMap[CertificateType::authority] = [](const std::string&) {};

    // Generate certificate file path
    certFilePath = generateCertFilePath(uploadPath);

    // install the certificate
    install(uploadPath, restore);

    this->emit_object_added();
}

Certificate::Certificate(sdbusplus::bus_t& bus, const std::string& objPath,
                         const CertificateType& type,
                         const std::string& installPath, X509_STORE& x509Store,
                         const std::string& pem, Watch* watchPtr,
                         Manager& parent, bool restore) :
    internal::CertificateInterface(
        bus, objPath.c_str(),
        internal::CertificateInterface::action::defer_emit),
    objectPath(objPath), certType(type), certInstallPath(installPath),
    certWatch(watchPtr), manager(parent)
{
    // Generate certificate file path
    certFilePath = generateUniqueFilePath(installPath);

    // install the certificate
    install(x509Store, pem, restore);

    this->emit_object_added();
}

Certificate::~Certificate()
{
    if (!fs::remove(certFilePath))
    {
        lg2::info("Certificate file not found! PATH:{PATH}", "PATH",
                  certFilePath);
    }
}

void Certificate::replace(const std::string filePath)
{
    manager.replaceCertificate(this, filePath);
}

void Certificate::install(const std::string& certSrcFilePath, bool restore)
{
    if (restore)
    {
        lg2::debug("Certificate install, FILEPATH:{FILEPATH}", "FILEPATH",
                   certSrcFilePath);
    }
    else
    {
        lg2::info("Certificate install, FILEPATH:{FILEPATH}", "FILEPATH",
                  certSrcFilePath);
    }

    // stop watch for user initiated certificate install
    if (certWatch != nullptr)
    {
        certWatch->stopWatch();
    }

    // Verify the certificate file
    fs::path file(certSrcFilePath);
    if (!fs::exists(file))
    {
        lg2::error("File is Missing, FILE:{FILE}", "FILE", certSrcFilePath);
        elog<InternalFailure>();
    }

    try
    {
        if (fs::file_size(certSrcFilePath) == 0)
        {
            // file is empty
            lg2::error("File is empty, FILE:{FILE}", "FILE", certSrcFilePath);
            elog<InvalidCertificateError>(
                InvalidCertificate::REASON("File is empty"));
        }
    }
    catch (const fs::filesystem_error& e)
    {
        // Log Error message
        lg2::error("File is empty, FILE:{FILE}, ERR:{ERR}", "FILE",
                   certSrcFilePath, "ERR", e);
        elog<InternalFailure>();
    }

    X509StorePtr x509Store = getX509Store(certSrcFilePath);

    // Load Certificate file into the X509 structure.
    internal::X509Ptr cert = loadCert(certSrcFilePath);

    // Perform validation
    validateCertificateAgainstStore(*x509Store, *cert);
    validateCertificateStartDate(*cert);
    validateCertificateInSSLContext(*cert);

    // Invoke type specific append private key function.
    if (auto it = appendKeyMap.find(certType); it == appendKeyMap.end())
    {
        lg2::error("Unsupported Type, TYPE:{TYPE}", "TYPE",
                   certificateTypeToString(certType));
        elog<InternalFailure>();
    }
    else
    {
        it->second(certSrcFilePath);
    }

    // Invoke type specific compare keys function.
    if (auto it = typeFuncMap.find(certType); it == typeFuncMap.end())
    {
        lg2::error("Unsupported Type, TYPE:{TYPE}", "TYPE",
                   certificateTypeToString(certType));
        elog<InternalFailure>();
    }
    else
    {
        it->second(certSrcFilePath);
    }

    copyCertificate(certSrcFilePath, certFilePath);
    storageUpdate();

    // Keep certificate ID
    certId = generateCertId(*cert);

    // Parse the certificate file and populate properties
    populateProperties(*cert);

    // restart watch
    if (certWatch != nullptr)
    {
        certWatch->startWatch();
    }
}

void Certificate::install(X509_STORE& x509Store, const std::string& pem,
                          bool restore)
{
    if (restore)
    {
        lg2::debug("Certificate install, PEM_STR:{PEM_STR}", "PEM_STR", pem);
    }
    else
    {
        lg2::info("Certificate install, PEM_STR:{PEM_STR} ", "PEM_STR", pem);
    }

    if (certType != CertificateType::authority)
    {
        lg2::error("Bulk install error: Unsupported Type; only authority "
                   "supports bulk install, TYPE:{TYPE}",
                   "TYPE", certificateTypeToString(certType));
        elog<InternalFailure>();
    }

    // stop watch for user initiated certificate install
    if (certWatch)
    {
        certWatch->stopWatch();
    }

    // Load Certificate file into the X509 structure.
    internal::X509Ptr cert = parseCert(pem);
    // Perform validation; no type specific compare keys function
    validateCertificateAgainstStore(x509Store, *cert);
    validateCertificateStartDate(*cert);
    validateCertificateInSSLContext(*cert);

    // Copy the PEM to the installation path
    dumpCertificate(pem, certFilePath);
    storageUpdate();
    // Keep certificate ID
    certId = generateCertId(*cert);
    // Parse the certificate file and populate properties
    populateProperties(*cert);
    // restart watch
    if (certWatch)
    {
        certWatch->startWatch();
    }
}

void Certificate::populateProperties()
{
    internal::X509Ptr cert = loadCert(certInstallPath);
    populateProperties(*cert);
}

std::string Certificate::getCertId() const
{
    return certId;
}

bool Certificate::isSame(const std::string& certPath)
{
    internal::X509Ptr cert = loadCert(certPath);
    return getCertId() == generateCertId(*cert);
}

void Certificate::storageUpdate()
{
    if (certType == CertificateType::authority)
    {
        // Create symbolic link in the certificate directory
        std::string certFileX509Path;
        try
        {
            if (!certFilePath.empty() &&
                fs::is_regular_file(fs::path(certFilePath)))
            {
                certFileX509Path =
                    generateAuthCertFileX509Path(certFilePath, certInstallPath);
                fs::create_symlink(fs::path(certFilePath),
                                   fs::path(certFileX509Path));
            }
        }
        catch (const std::exception& e)
        {
            lg2::error("Failed to create symlink for certificate, ERR:{ERR},"
                       "FILE:{FILE}, SYMLINK:{SYMLINK}",
                       "ERR", e, "FILE", certFilePath, "SYMLINK",
                       certFileX509Path);
            elog<InternalFailure>();
        }
    }
}

void Certificate::populateProperties(X509& cert)
{
    // Update properties if no error thrown
    BIOMemPtr certBio(BIO_new(BIO_s_mem()), BIO_free);
    PEM_write_bio_X509(certBio.get(), &cert);
    BufMemPtr certBuf(BUF_MEM_new(), BUF_MEM_free);
    BUF_MEM* buf = certBuf.get();
    BIO_get_mem_ptr(certBio.get(), &buf);
    std::string certStr(buf->data, buf->length);
    certificateString(certStr);

    static const int maxKeySize = 4096;
    char subBuffer[maxKeySize] = {0};
    BIOMemPtr subBio(BIO_new(BIO_s_mem()), BIO_free);
    // This pointer cannot be freed independantly.
    X509_NAME* sub = X509_get_subject_name(&cert);
    X509_NAME_print_ex(subBio.get(), sub, 0, XN_FLAG_SEP_COMMA_PLUS);
    BIO_read(subBio.get(), subBuffer, maxKeySize);
    subject(subBuffer);

    char issuerBuffer[maxKeySize] = {0};
    BIOMemPtr issuerBio(BIO_new(BIO_s_mem()), BIO_free);
    // This pointer cannot be freed independantly.
    X509_NAME* issuerName = X509_get_issuer_name(&cert);
    X509_NAME_print_ex(issuerBio.get(), issuerName, 0, XN_FLAG_SEP_COMMA_PLUS);
    BIO_read(issuerBio.get(), issuerBuffer, maxKeySize);
    issuer(issuerBuffer);

    std::vector<std::string> keyUsageList;
    ASN1_BIT_STRING* usage;

    // Go through each usage in the bit string and convert to
    // corresponding string value
    if ((usage = static_cast<ASN1_BIT_STRING*>(
             X509_get_ext_d2i(&cert, NID_key_usage, nullptr, nullptr))))
    {
        for (auto i = 0; i < usage->length; ++i)
        {
            for (auto& x : keyUsageToRfStr)
            {
                if (x.first & usage->data[i])
                {
                    keyUsageList.push_back(x.second);
                    break;
                }
            }
        }
    }

    EXTENDED_KEY_USAGE* extUsage;
    if ((extUsage = static_cast<EXTENDED_KEY_USAGE*>(
             X509_get_ext_d2i(&cert, NID_ext_key_usage, nullptr, nullptr))))
    {
        for (int i = 0; i < sk_ASN1_OBJECT_num(extUsage); i++)
        {
            keyUsageList.push_back(extendedKeyUsageToRfStr[OBJ_obj2nid(
                sk_ASN1_OBJECT_value(extUsage, i))]);
        }
    }
    keyUsage(keyUsageList);

    int days = 0;
    int secs = 0;

    ASN1TimePtr epoch(ASN1_TIME_new(), ASN1_STRING_free);
    // Set time to 00:00am GMT, Jan 1 1970; format: YYYYMMDDHHMMSSZ
    ASN1_TIME_set_string(epoch.get(), "19700101000000Z");

    static const uint64_t dayToSeconds = 24 * 60 * 60;
    ASN1_TIME* notAfter = X509_get_notAfter(&cert);
    ASN1_TIME_diff(&days, &secs, epoch.get(), notAfter);
    validNotAfter((days * dayToSeconds) + secs);

    ASN1_TIME* notBefore = X509_get_notBefore(&cert);
    ASN1_TIME_diff(&days, &secs, epoch.get(), notBefore);
    validNotBefore((days * dayToSeconds) + secs);
}

void Certificate::checkAndAppendPrivateKey(const std::string& filePath)
{
    BIOMemPtr keyBio(BIO_new(BIO_s_file()), ::BIO_free);
    if (!keyBio)
    {
        lg2::error("Error occurred during BIO_s_file call, FILE:{FILE}", "FILE",
                   filePath);
        elog<InternalFailure>();
    }
    BIO_read_filename(keyBio.get(), filePath.c_str());

    EVPPkeyPtr priKey(
        PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr),
        ::EVP_PKEY_free);
    if (!priKey)
    {
        lg2::info("Private key not present in file, FILE:{FILE}", "FILE",
                  filePath);
        fs::path privateKeyFile = fs::path(certInstallPath).parent_path();
        privateKeyFile = privateKeyFile / defaultPrivateKeyFileName;
        if (!fs::exists(privateKeyFile))
        {
            lg2::error("Private key file is not found, FILE:{FILE}", "FILE",
                       privateKeyFile);
            elog<InternalFailure>();
        }

        std::ifstream privKeyFileStream;
        std::ofstream certFileStream;
        privKeyFileStream.exceptions(std::ifstream::failbit |
                                     std::ifstream::badbit |
                                     std::ifstream::eofbit);
        certFileStream.exceptions(std::ofstream::failbit |
                                  std::ofstream::badbit |
                                  std::ofstream::eofbit);
        try
        {
            privKeyFileStream.open(privateKeyFile);
            certFileStream.open(filePath, std::ios::app);
            certFileStream << std::endl; // insert line break
            certFileStream << privKeyFileStream.rdbuf() << std::flush;
            privKeyFileStream.close();
            certFileStream.close();
        }
        catch (const std::exception& e)
        {
            lg2::error(
                "Failed to append private key, ERR:{ERR}, SRC:{SRC}, DST:{DST}",
                "ERR", e, "SRC", privateKeyFile, "DST", filePath);
            elog<InternalFailure>();
        }
    }
}

bool Certificate::compareKeys(const std::string& filePath)
{
    lg2::info("Certificate compareKeys, FILEPATH:{FILEPATH}", "FILEPATH",
              filePath);
    internal::X509Ptr cert(X509_new(), ::X509_free);
    if (!cert)
    {
        lg2::error(
            "Error occurred during X509_new call, FILE:{FILE}, ERRCODE:{ERRCODE}",
            "FILE", filePath, "ERRCODE", ERR_get_error());
        elog<InternalFailure>();
    }

    BIOMemPtr bioCert(BIO_new_file(filePath.c_str(), "rb"), ::BIO_free);
    if (!bioCert)
    {
        lg2::error("Error occurred during BIO_new_file call, FILE:{FILE}",
                   "FILE", filePath);
        elog<InternalFailure>();
    }

    X509* x509 = cert.get();
    PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr);

    EVPPkeyPtr pubKey(X509_get_pubkey(cert.get()), ::EVP_PKEY_free);
    if (!pubKey)
    {
        lg2::error(
            "Error occurred during X509_get_pubkey, FILE:{FILE}, ERRCODE:{ERRCODE}",
            "FILE", filePath, "ERRCODE", ERR_get_error());
        elog<InvalidCertificateError>(
            InvalidCertificate::REASON("Failed to get public key info"));
    }

    BIOMemPtr keyBio(BIO_new(BIO_s_file()), ::BIO_free);
    if (!keyBio)
    {
        lg2::error("Error occurred during BIO_s_file call, FILE:{FILE}", "FILE",
                   filePath);
        elog<InternalFailure>();
    }
    BIO_read_filename(keyBio.get(), filePath.c_str());

    EVPPkeyPtr priKey(
        PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr),
        ::EVP_PKEY_free);
    if (!priKey)
    {
        lg2::error(
            "Error occurred during PEM_read_bio_PrivateKey, FILE:{FILE}, ERRCODE:{ERRCODE}",
            "FILE", filePath, "ERRCODE", ERR_get_error());
        elog<InvalidCertificateError>(
            InvalidCertificate::REASON("Failed to get private key info"));
    }

#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
    int32_t rc = EVP_PKEY_cmp(priKey.get(), pubKey.get());
#else
    int32_t rc = EVP_PKEY_eq(priKey.get(), pubKey.get());
#endif
    if (rc != 1)
    {
        lg2::error(
            "Private key is not matching with Certificate, FILE:{FILE}, ERRCODE:{ERRCODE}",
            "FILE", filePath, "ERRCODE", rc);
        return false;
    }
    return true;
}

void Certificate::delete_()
{
    manager.deleteCertificate(this);
}

std::string Certificate::getObjectPath()
{
    return objectPath;
}

std::string Certificate::getCertFilePath()
{
    return certFilePath;
}

void Certificate::setCertFilePath(const std::string& path)
{
    certFilePath = path;
}

void Certificate::setCertInstallPath(const std::string& path)
{
    certInstallPath = path;
}

} // namespace phosphor::certs
