#include "config.h"

#include "certificate.hpp"
#include "certs_manager.hpp"
#include "csr.hpp"

#include <openssl/bio.h>
#include <openssl/ossl_typ.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <systemd/sd-event.h>
#include <unistd.h>

#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <iterator>
#include <memory>
#include <new>
#include <sdbusplus/bus.hpp>
#include <sdeventplus/event.hpp>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include <xyz/openbmc_project/Certs/error.hpp>
#include <xyz/openbmc_project/Common/error.hpp>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace phosphor::certs
{
namespace
{
namespace fs = std::filesystem;
using ::sdbusplus::xyz::openbmc_project::Certs::Error::InvalidCertificate;
using ::sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
using ::testing::Eq;
using ::testing::Return;
// Compares two files; returns true only if the two are the same
bool compareFiles(const std::string& file1, const std::string& file2)
{
    std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
    std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);

    if (f1.fail() || f2.fail())
    {
        return false; // file problem
    }

    if (f1.tellg() != f2.tellg())
    {
        return false; // size mismatch
    }

    // seek back to beginning and use std::equal to compare contents
    f1.seekg(0, std::ifstream::beg);
    f2.seekg(0, std::ifstream::beg);
    return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
                      std::istreambuf_iterator<char>(),
                      std::istreambuf_iterator<char>(f2.rdbuf()));
}

/**
 * Class to generate certificate file and test verification of certificate file
 */
class TestCertificates : public ::testing::Test
{
  public:
    TestCertificates() : bus(sdbusplus::bus::new_default())
    {
    }
    void SetUp() override
    {
        char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
        auto dirPtr = mkdtemp(dirTemplate);
        if (dirPtr == nullptr)
        {
            throw std::bad_alloc();
        }
        certDir = std::string(dirPtr) + "/certs";
        fs::create_directories(certDir);

        createNewCertificate();
    }

    void TearDown() override
    {
        fs::remove_all(certDir);
        fs::remove(certificateFile);
        fs::remove(CSRFile);
        fs::remove(privateKeyFile);
        fs::remove_all("demoCA");
    }

    void createNewCertificate(bool setNewCertId = false)
    {
        certificateFile = "cert.pem";
        CSRFile = "domain.csr";
        privateKeyFile = "privkey.pem";
        rsaPrivateKeyFilePath = certDir + "/.rsaprivkey.pem";
        std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
        cmd += "-keyout cert.pem -out cert.pem -days 365000 -nodes";
        cmd += " -subj /O=openbmc-project.xyz/CN=localhost";

        if (setNewCertId)
        {
            cmd += std::to_string(certId++);
        }

        auto val = std::system(cmd.c_str());
        if (val)
        {
            std::cout << "COMMAND Error: " << val << std::endl;
        }
    }

    void createNeverExpiredRootCertificate()
    {
        // remove the old cert
        fs::remove(certificateFile);

        // The following routines create a cert that has NotBefore
        // set to 1970/01/01 and NotAfter set to 9999/12/31 via the
        // OpenSSL CA application.
        certificateFile = "cert.pem";
        ASSERT_EQ(std::system("mkdir -p demoCA"), 0);
        ASSERT_EQ(std::system("mkdir -p demoCA/private/"), 0);
        ASSERT_EQ(std::system("mkdir -p demoCA/newcerts/"), 0);
        ASSERT_EQ(std::system("touch demoCA/index.txt"), 0);
        ASSERT_EQ(std::system("echo 1000 > demoCA/serial"), 0);
        ASSERT_EQ(
            std::system(
                "openssl req -x509 -sha256 -newkey rsa:2048 -keyout "
                "demoCA/private/cakey.pem -out demoCA/cacert.pem -nodes "
                "-subj /O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-ca"),
            0);
        ASSERT_EQ(std::system(
                      "openssl req -new -newkey rsa:2048 -nodes -keyout "
                      "demoCA/server.key -out demoCA/server.csr -subj "
                      "/O=openbmc-project.xyz/C=US/ST=CA/CN=localhost-server"),
                  0);
        ASSERT_EQ(
            std::system(
                "openssl ca -batch -startdate 19700101000000Z -enddate "
                "99991231235959Z -out cert.pem -infiles demoCA/server.csr"),
            0);
    }

    bool compareFiles(const std::string& file1, const std::string& file2)
    {
        std::ifstream f1(file1, std::ifstream::binary | std::ifstream::ate);
        std::ifstream f2(file2, std::ifstream::binary | std::ifstream::ate);

        if (f1.fail() || f2.fail())
        {
            return false; // file problem
        }

        if (f1.tellg() != f2.tellg())
        {
            return false; // size mismatch
        }

        // seek back to beginning and use std::equal to compare contents
        f1.seekg(0, std::ifstream::beg);
        f2.seekg(0, std::ifstream::beg);
        return std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
                          std::istreambuf_iterator<char>(),
                          std::istreambuf_iterator<char>(f2.rdbuf()));
    }

    std::string getCertSubjectNameHash(const std::string& certFilePath)
    {
        std::unique_ptr<X509, decltype(&::X509_free)> cert(X509_new(),
                                                           ::X509_free);
        if (!cert)
        {
            std::string();
        }

        std::unique_ptr<BIO, decltype(&::BIO_free)> bioCert(
            BIO_new_file(certFilePath.c_str(), "rb"), ::BIO_free);
        if (!bioCert)
        {
            std::string();
        }

        X509* x509 = cert.get();
        if (!PEM_read_bio_X509(bioCert.get(), &x509, nullptr, nullptr))
        {
            std::string();
        }

        unsigned long hash = X509_subject_name_hash(cert.get());
        static constexpr auto AUTH_CERT_HASH_LENGTH = 9;
        char hashBuf[AUTH_CERT_HASH_LENGTH];
        sprintf(hashBuf, "%08lx", hash);
        return std::string(hashBuf);
    }

  protected:
    sdbusplus::bus::bus bus;
    std::string certificateFile, CSRFile, privateKeyFile, rsaPrivateKeyFilePath;

    std::string certDir;
    uint64_t certId;
};

class MainApp
{
  public:
    MainApp(phosphor::certs::Manager* manager,
            phosphor::certs::CSR* csr = nullptr) :
        manager(manager),
        csr_(csr)
    {
    }
    void install(std::string& path)
    {
        manager->install(path);
    }
    void delete_()
    {
        manager->deleteAll();
    }

    std::string generateCSR(std::vector<std::string> alternativeNames,
                            std::string challengePassword, std::string city,
                            std::string commonName, std::string contactPerson,
                            std::string country, std::string email,
                            std::string givenName, std::string initials,
                            int64_t keyBitLength, std::string keyCurveId,
                            std::string keyPairAlgorithm,
                            std::vector<std::string> keyUsage,
                            std::string organization,
                            std::string organizationalUnit, std::string state,
                            std::string surname, std::string unstructuredName)
    {
        return (manager->generateCSR(
            alternativeNames, challengePassword, city, commonName,
            contactPerson, country, email, givenName, initials, keyBitLength,
            keyCurveId, keyPairAlgorithm, keyUsage, organization,
            organizationalUnit, state, surname, unstructuredName));
    }
    std::string csr()
    {
        return (csr_->csr());
    }
    phosphor::certs::Manager* manager;
    phosphor::certs::CSR* csr_;
};

class ManagerInTest : public phosphor::certs::Manager
{
  public:
    static constexpr std::string_view unitToRestartInTest =
        "xyz.openbmc_project.awesome-service";
    ManagerInTest(sdbusplus::bus::bus& bus, sdeventplus::Event& event,
                  const char* path, CertificateType type,
                  const std::string& unit, const std::string& installPath) :
        Manager(bus, event, path, type, unit, installPath)
    {
    }

    MOCK_METHOD(void, reloadOrReset, (const std::string&), (override));
};

/** @brief Check if server install routine is invoked for server setup
 */
TEST_F(TestCertificates, InvokeServerInstall)
{
    std::string endpoint("https");
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          installPath);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);
    EXPECT_TRUE(fs::exists(verifyPath));
}

/** @brief Check if client install routine is invoked for client setup
 */
TEST_F(TestCertificates, InvokeClientInstall)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          installPath);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);
    EXPECT_TRUE(fs::exists(verifyPath));
}

/** @brief Check if storage install routine is invoked for storage setup
 */
TEST_F(TestCertificates, InvokeAuthorityInstall)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          verifyDir);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    MainApp mainApp(&manager);
    // install the default certificate that's valid from today to 100 years
    // later
    mainApp.install(certificateFile);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    ASSERT_EQ(certs.size(), 1);
    // check some attributes as well
    EXPECT_EQ(certs.front()->validNotAfter() - certs.front()->validNotBefore(),
              365000ULL * 24 * 3600);
    EXPECT_EQ(certs.front()->subject(), "O=openbmc-project.xyz,CN=localhost");
    EXPECT_EQ(certs.front()->issuer(), "O=openbmc-project.xyz,CN=localhost");

    std::string verifyPath =
        verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";

    // Check that certificate has been created at installation directory
    EXPECT_FALSE(fs::is_empty(verifyDir));
    EXPECT_TRUE(fs::exists(verifyPath));

    // Check that installed cert is identical to input one
    EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
}

/** @brief Check if storage install routine is invoked for storage setup
 */
TEST_F(TestCertificates, InvokeAuthorityInstallNeverExpiredRootCert)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          certDir);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    MainApp mainApp(&manager);

    // install the certificate that's valid from the Unix Epoch to Dec 31, 9999
    createNeverExpiredRootCertificate();
    mainApp.install(certificateFile);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    EXPECT_EQ(certs.front()->validNotBefore(), 0);
    EXPECT_EQ(certs.front()->validNotAfter(), 253402300799ULL);

    std::string verifyPath =
        verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";

    // Check that certificate has been created at installation directory
    EXPECT_FALSE(fs::is_empty(verifyDir));
    EXPECT_TRUE(fs::exists(verifyPath));

    // Check that installed cert is identical to input one
    EXPECT_TRUE(compareFiles(certificateFile, verifyPath));
}

/** @brief Check if in authority mode user can't install the same
 * certificate twice.
 */
TEST_F(TestCertificates, InvokeInstallSameCertTwice)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          std::move(certDir));
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    EXPECT_FALSE(certs.empty());

    // Check that certificate has been created at installation directory
    std::string verifyPath =
        verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
    EXPECT_FALSE(fs::is_empty(verifyDir));
    EXPECT_TRUE(fs::exists(verifyPath));

    // Check that installed cert is identical to input one
    EXPECT_TRUE(compareFiles(certificateFile, verifyPath));

    using NotAllowed =
        sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
    EXPECT_THROW(
        {
            try
            {
                // Try to install the same certificate second time
                mainApp.install(certificateFile);
            }
            catch (const NotAllowed& e)
            {
                throw;
            }
        },
        NotAllowed);

    // Check that the original certificate has been not removed
    EXPECT_FALSE(fs::is_empty(verifyDir));
    EXPECT_TRUE(fs::exists(verifyPath));
}

/** @brief Check if in authority mode user can install a certificate with
 * certain subject hash twice.
 */
TEST_F(TestCertificates, InvokeInstallSameSubjectTwice)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          certDir);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return())
        .WillOnce(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    EXPECT_FALSE(certs.empty());

    // Check that certificate has been created at installation directory
    std::string verifyPath0 =
        verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
    EXPECT_FALSE(fs::is_empty(verifyDir));
    EXPECT_TRUE(fs::exists(verifyPath0));

    // Check that installed cert is identical to input one
    EXPECT_TRUE(compareFiles(certificateFile, verifyPath0));

    // Prepare second certificate with the same subject
    createNewCertificate();

    // Install second certificate
    mainApp.install(certificateFile);

    // Expect there are exactly two certificates in the collection
    EXPECT_EQ(certs.size(), 2);

    // Check that certificate has been created at installation directory
    std::string verifyPath1 =
        verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".1";
    EXPECT_TRUE(fs::exists(verifyPath1));

    // Check that installed cert is identical to input one
    EXPECT_TRUE(compareFiles(certificateFile, verifyPath1));

    // Check that the original/first certificate has been not removed
    EXPECT_FALSE(fs::is_empty(verifyDir));
    EXPECT_TRUE(fs::exists(verifyPath0));
}

/** @brief Check if in authority mode user can't install more than
 * maxNumAuthorityCertificates certificates.
 */
TEST_F(TestCertificates, InvokeInstallAuthCertLimit)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          certDir);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillRepeatedly(Return());
    MainApp mainApp(&manager);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    std::vector<std::string> verifyPaths;

    // Prepare maximum number of ceritificates
    for (std::size_t i = 0; i < maxNumAuthorityCertificates; ++i)
    {
        // Prepare new certificatate
        createNewCertificate(true);

        // Install ceritificate
        mainApp.install(certificateFile);

        // Check number of certificates in the collection
        EXPECT_EQ(certs.size(), i + 1);

        // Check that certificate has been created at installation directory
        std::string verifyPath =
            verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";
        EXPECT_FALSE(fs::is_empty(verifyDir));
        EXPECT_TRUE(fs::exists(verifyPath));

        // Check that installed cert is identical to input one
        EXPECT_TRUE(compareFiles(certificateFile, verifyPath));

        // Save current certificate file for later check
        verifyPaths.push_back(verifyPath);
    }

    // Prepare new certificatate
    createNewCertificate(true);

    using NotAllowed =
        sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
    EXPECT_THROW(
        {
            try
            {
                // Try to install one more certificate
                mainApp.install(certificateFile);
            }
            catch (const NotAllowed& e)
            {
                throw;
            }
        },
        NotAllowed);

    // Check that the original certificate has been not removed
    EXPECT_FALSE(fs::is_empty(verifyDir));
    for (size_t i = 0; i < maxNumAuthorityCertificates; ++i)
    {
        EXPECT_TRUE(fs::exists(verifyPaths[i]));
    }
}

/** @brief Compare the installed certificate with the copied certificate
 */
TEST_F(TestCertificates, CompareInstalledCertificate)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          installPath);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);
    EXPECT_TRUE(fs::exists(verifyPath));
    EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
}

/** @brief Check if install fails if certificate file is not found
 */
TEST_F(TestCertificates, TestNoCertificateFile)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    std::string uploadFile = "nofile.pem";
    EXPECT_THROW(
        {
            try
            {
                auto event = sdeventplus::Event::get_default();
                // Attach the bus to sd_event to service user requests
                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
                ManagerInTest manager(bus, event, objPath.c_str(), type,
                                      verifyUnit, installPath);
                MainApp mainApp(&manager);
                mainApp.install(uploadFile);
            }
            catch (const InternalFailure& e)
            {
                throw;
            }
        },
        InternalFailure);
    EXPECT_FALSE(fs::exists(verifyPath));
}

/** @brief Test replacing existing certificate
 */
TEST_F(TestCertificates, TestReplaceCertificate)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          std::move(installPath));
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return())
        .WillOnce(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);
    EXPECT_TRUE(fs::exists(verifyPath));
    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();
    EXPECT_FALSE(certs.empty());
    EXPECT_NE(certs[0], nullptr);
    certs[0]->replace(certificateFile);
    EXPECT_TRUE(fs::exists(verifyPath));
}

/** @brief Test replacing existing certificate
 */
TEST_F(TestCertificates, TestAuthorityReplaceCertificate)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          certDir);
    constexpr const unsigned int REPLACE_ITERATIONS = 10;
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .Times(REPLACE_ITERATIONS + 1)
        .WillRepeatedly(Return());
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    for (unsigned int i = 0; i < REPLACE_ITERATIONS; i++)
    {
        // Certificate successfully installed
        EXPECT_FALSE(certs.empty());

        std::string verifyPath =
            verifyDir + "/" + getCertSubjectNameHash(certificateFile) + ".0";

        // Check that certificate has been created at installation directory
        EXPECT_FALSE(fs::is_empty(verifyDir));
        EXPECT_TRUE(fs::exists(verifyPath));

        // Check that installed cert is identical to input one
        EXPECT_TRUE(compareFiles(certificateFile, verifyPath));

        // Create new certificate
        createNewCertificate(true);

        certs[0]->replace(certificateFile);

        // Verify that old certificate has been removed
        EXPECT_FALSE(fs::exists(verifyPath));
    }
}

/** @brief Test verifiing if delete function works.
 */
TEST_F(TestCertificates, TestStorageDeleteCertificate)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Authority;
    std::string verifyDir(certDir);
    std::string verifyUnit((ManagerInTest::unitToRestartInTest));
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          certDir);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillRepeatedly(Return());
    MainApp mainApp(&manager);

    // Check if certificate placeholder dir is empty
    EXPECT_TRUE(fs::is_empty(verifyDir));
    mainApp.install(certificateFile);

    // Create new certificate
    createNewCertificate(true);
    mainApp.install(certificateFile);

    createNewCertificate(true);
    mainApp.install(certificateFile);

    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();

    // All 3 certificates successfully installed and added to manager
    EXPECT_EQ(certs.size(), 3);

    // Check if certificate placeholder is not empty, there should be 3
    // certificates
    EXPECT_FALSE(fs::is_empty(verifyDir));

    certs[0]->delete_();
    EXPECT_EQ(certs.size(), 2);

    certs[0]->delete_();
    EXPECT_EQ(certs.size(), 1);

    certs[0]->delete_();
    EXPECT_EQ(certs.size(), 0);

    // Check if certificate placeholder is empty.
    EXPECT_TRUE(fs::is_empty(verifyDir));
}

/** @brief Check if install fails if certificate file is empty
 */
TEST_F(TestCertificates, TestEmptyCertificateFile)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    std::string emptyFile("emptycert.pem");
    std::ofstream ofs;
    ofs.open(emptyFile, std::ofstream::out);
    ofs.close();
    EXPECT_THROW(
        {
            try
            {
                auto event = sdeventplus::Event::get_default();
                // Attach the bus to sd_event to service user requests
                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
                ManagerInTest manager(bus, event, objPath.c_str(), type,
                                      verifyUnit, installPath);
                MainApp mainApp(&manager);
                mainApp.install(emptyFile);
            }
            catch (const InvalidCertificate& e)
            {
                throw;
            }
        },
        InvalidCertificate);
    EXPECT_FALSE(fs::exists(verifyPath));
    fs::remove(emptyFile);
}

/** @brief Check if install fails if certificate file is corrupted
 */
TEST_F(TestCertificates, TestInvalidCertificateFile)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;

    std::ofstream ofs;
    ofs.open(certificateFile, std::ofstream::out);
    ofs << "-----BEGIN CERTIFICATE-----";
    ofs << "ADD_SOME_INVALID_DATA_INTO_FILE";
    ofs << "-----END CERTIFICATE-----";
    ofs.close();

    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    EXPECT_THROW(
        {
            try
            {
                auto event = sdeventplus::Event::get_default();
                // Attach the bus to sd_event to service user requests
                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
                ManagerInTest manager(bus, event, objPath.c_str(), type,
                                      verifyUnit, installPath);
                MainApp mainApp(&manager);
                mainApp.install(certificateFile);
            }
            catch (const InvalidCertificate& e)
            {
                throw;
            }
        },
        InvalidCertificate);
    EXPECT_FALSE(fs::exists(verifyPath));
}

/**
 * Class to generate private and certificate only file and test verification
 */
class TestInvalidCertificate : public ::testing::Test
{
  public:
    TestInvalidCertificate() : bus(sdbusplus::bus::new_default())
    {
    }
    void SetUp() override
    {
        char dirTemplate[] = "/tmp/FakeCerts.XXXXXX";
        auto dirPtr = mkdtemp(dirTemplate);
        if (dirPtr == nullptr)
        {
            throw std::bad_alloc();
        }
        certDir = std::string(dirPtr) + "/certs";
        fs::create_directories(certDir);
        certificateFile = "cert.pem";
        keyFile = "key.pem";
        std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 ";
        cmd += "-keyout key.pem -out cert.pem -days 3650 ";
        cmd += "-subj "
               "/O=openbmc-project.xyz/CN=localhost"
               " -nodes";

        auto val = std::system(cmd.c_str());
        if (val)
        {
            std::cout << "command Error: " << val << std::endl;
        }
    }
    void TearDown() override
    {
        fs::remove_all(certDir);
        fs::remove(certificateFile);
        fs::remove(keyFile);
    }

  protected:
    sdbusplus::bus::bus bus;
    std::string certificateFile;
    std::string keyFile;
    std::string certDir;
};

/** @brief Check install fails if private key is missing in certificate file
 */
TEST_F(TestInvalidCertificate, TestMissingPrivateKey)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    EXPECT_THROW(
        {
            try
            {
                auto event = sdeventplus::Event::get_default();
                // Attach the bus to sd_event to service user requests
                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
                ManagerInTest manager(bus, event, objPath.c_str(), type,
                                      verifyUnit, installPath);
                MainApp mainApp(&manager);
                mainApp.install(certificateFile);
            }
            catch (const InternalFailure& e)
            {
                throw;
            }
        },
        InternalFailure);
    EXPECT_FALSE(fs::exists(verifyPath));
}

/** @brief Check install fails if ceritificate is missing in certificate file
 */
TEST_F(TestInvalidCertificate, TestMissingCeritificate)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;
    std::string installPath(certDir + "/" + keyFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    EXPECT_THROW(
        {
            try
            {
                auto event = sdeventplus::Event::get_default();
                // Attach the bus to sd_event to service user requests
                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
                ManagerInTest manager(bus, event, objPath.c_str(), type,
                                      verifyUnit, installPath);
                MainApp mainApp(&manager);
                mainApp.install(keyFile);
            }
            catch (const InternalFailure& e)
            {
                throw;
            }
        },
        InvalidCertificate);
    EXPECT_FALSE(fs::exists(verifyPath));
}

/** @brief Check if error is thrown when multiple certificates are installed
 *  At present only one certificate per service is allowed
 */
TEST_F(TestCertificates, TestCertInstallNotAllowed)
{
    using NotAllowed =
        sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Client;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, objPath.c_str(), type, verifyUnit,
                          installPath);
    MainApp mainApp(&manager);
    mainApp.install(certificateFile);
    EXPECT_TRUE(fs::exists(verifyPath));
    EXPECT_THROW(
        {
            try
            {
                // install second certificate
                mainApp.install(certificateFile);
            }
            catch (const NotAllowed& e)
            {
                throw;
            }
        },
        NotAllowed);
}

TEST_F(TestCertificates, TestGenerateCSR)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("HYB");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("0");
    std::string keyPairAlgorithm("RSA");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    std::string csrData("");
    // generateCSR takes considerable time to create CSR and privateKey Files
    EXPECT_FALSE(fs::exists(CSRPath));
    EXPECT_FALSE(fs::exists(privateKeyPath));
    EXPECT_THROW(
        {
            try
            {
                csrData = csr.csr();
            }
            catch (const InternalFailure& e)
            {
                throw;
            }
        },
        InternalFailure);
    // wait for 10 sec to get CSR and privateKey Files generated
    sleep(10);
    EXPECT_TRUE(fs::exists(CSRPath));
    EXPECT_TRUE(fs::exists(privateKeyPath));
    csrData = csr.csr();
    ASSERT_NE("", csrData.c_str());
}

/** @brief Check if ECC key pair is generated when user is not given algorithm
 * type. At present RSA and EC key pair algorithm are supported
 */
TEST_F(TestCertificates, TestGenerateCSRwithEmptyKeyPairAlgorithm)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("HYB");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("");
    std::string keyPairAlgorithm("");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    sleep(10);
    EXPECT_TRUE(fs::exists(CSRPath));
    EXPECT_TRUE(fs::exists(privateKeyPath));
}

/** @brief Check if error is thrown when giving un supported key pair
 * algorithm. At present RSA and EC key pair algorithm are supported
 */
TEST_F(TestCertificates, TestGenerateCSRwithUnsupportedKeyPairAlgorithm)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("HYB");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("secp521r1");
    std::string keyPairAlgorithm("UnSupportedAlgorithm");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    EXPECT_FALSE(fs::exists(CSRPath));
    EXPECT_FALSE(fs::exists(privateKeyPath));
}

/** @brief Check if error is thrown when NID_undef is returned for given key
 * curve id
 */
TEST_F(TestCertificates, TestECKeyGenerationwithNIDundefCase)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("BLR");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("DummyCurveName");
    std::string keyPairAlgorithm("EC");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    EXPECT_FALSE(fs::exists(CSRPath));
    EXPECT_FALSE(fs::exists(privateKeyPath));
}

/** @brief Check default Key Curve Id is used if given curve id is empty
 */
TEST_F(TestCertificates, TestECKeyGenerationwithDefaultKeyCurveId)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("BLR");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("");
    std::string keyPairAlgorithm("EC");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    sleep(10);
    EXPECT_TRUE(fs::exists(CSRPath));
    EXPECT_TRUE(fs::exists(privateKeyPath));
}

/** @brief Check if error is not thrown to generate EC key pair
 */
TEST_F(TestCertificates, TestECKeyGeneration)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("BLR");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("secp521r1");
    std::string keyPairAlgorithm("EC");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    std::cout << "CSRPath: " << CSRPath << std::endl
              << "privateKeyPath: " << privateKeyPath << std::endl;
    sleep(10);
    EXPECT_TRUE(fs::exists(CSRPath));
    EXPECT_TRUE(fs::exists(privateKeyPath));
}

/** @brief Check error is thrown if giving unsupported key bit length to
 * generate rsa key
 */
TEST_F(TestCertificates, TestRSAKeyWithUnsupportedKeyBitLength)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("BLR");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(4096);
    std::string keyCurveId("secp521r1");
    std::string keyPairAlgorithm("RSA");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    EXPECT_FALSE(fs::exists(CSRPath));
    EXPECT_FALSE(fs::exists(privateKeyPath));
}

/** @brief Check error is thrown if generated rsa key file is not present
 */
TEST_F(TestCertificates, TestRSAKeyFileNotPresentCase)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("BLR");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("secp521r1");
    std::string keyPairAlgorithm("RSA");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));

    // Removing generated RSA key file
    fs::remove(rsaPrivateKeyFilePath);

    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    EXPECT_FALSE(fs::exists(CSRPath));
    EXPECT_FALSE(fs::exists(privateKeyPath));
}

/** @brief Check private key file is created from generated rsa key file is
 * `present
 */
TEST_F(TestCertificates, TestRSAKeyFromRSAKeyFileIsWrittenIntoPrivateKeyFile)
{
    std::string endpoint("https");
    std::string unit;
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyPath(installPath);
    std::string CSRPath(certDir + "/" + CSRFile);
    std::string privateKeyPath(certDir + "/" + privateKeyFile);
    std::vector<std::string> alternativeNames{"localhost1", "localhost2"};
    std::string challengePassword("Password");
    std::string city("BLR");
    std::string commonName("abc.com");
    std::string contactPerson("Admin");
    std::string country("IN");
    std::string email("admin@in.ibm.com");
    std::string givenName("givenName");
    std::string initials("G");
    int64_t keyBitLength(2048);
    std::string keyCurveId("secp521r1");
    std::string keyPairAlgorithm("RSA");
    std::vector<std::string> keyUsage{"serverAuth", "clientAuth"};
    std::string organization("IBM");
    std::string organizationalUnit("orgUnit");
    std::string state("TS");
    std::string surname("surname");
    std::string unstructuredName("unstructuredName");
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                    std::move(installPath));
    Status status;
    CSR csr(bus, objPath.c_str(), CSRPath.c_str(), status);
    MainApp mainApp(&manager, &csr);
    mainApp.generateCSR(alternativeNames, challengePassword, city, commonName,
                        contactPerson, country, email, givenName, initials,
                        keyBitLength, keyCurveId, keyPairAlgorithm, keyUsage,
                        organization, organizationalUnit, state, surname,
                        unstructuredName);
    sleep(10);
    EXPECT_TRUE(fs::exists(CSRPath));
    EXPECT_TRUE(fs::exists(privateKeyPath));
}

/** @brief Check RSA key is generated during application startup*/
TEST_F(TestCertificates, TestGenerateRSAPrivateKeyFile)
{
    std::string endpoint("https");
    CertificateType type = CertificateType::Server;
    std::string installPath(certDir + "/" + certificateFile);
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    auto objPath = std::string(objectNamePrefix) + '/' +
                   certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();

    EXPECT_FALSE(fs::exists(rsaPrivateKeyFilePath));
    Manager manager(bus, event, objPath.c_str(), type, verifyUnit, installPath);
    EXPECT_TRUE(fs::exists(rsaPrivateKeyFilePath));
}

/**
 * Class to test Authorities List installation and replacement
 */
class AuthoritiesListTest : public testing::Test
{
  public:
    AuthoritiesListTest() :
        bus(sdbusplus::bus::new_default()),
        authoritiesListFolder(
            Certificate::generateUniqueFilePath(fs::temp_directory_path()))
    {
        fs::create_directory(authoritiesListFolder);
        createAuthoritiesList(maxNumAuthorityCertificates);
    }
    ~AuthoritiesListTest() override
    {
        fs::remove_all(authoritiesListFolder);
    }

  protected:
    // Creates a testing authorities list which consists of |count| root
    // certificates
    void createAuthoritiesList(int count)
    {
        fs::path srcFolder = fs::temp_directory_path();
        srcFolder = Certificate::generateUniqueFilePath(srcFolder);
        fs::create_directory(srcFolder);
        createSingleAuthority(srcFolder, "root_0");
        sourceAuthoritiesListFile = srcFolder / "root_0_cert";
        for (int i = 1; i < count; ++i)
        {
            std::string name = "root_" + std::to_string(i);
            createSingleAuthority(srcFolder, name);
            appendContentFromFile(sourceAuthoritiesListFile,
                                  srcFolder / (name + "_cert"));
        }
    }

    // Creates a single self-signed root certificate in given |path|; the key
    // will be |path|/|cn|_key, the cert will be |path|/|cn|_cert, and the cn
    // will be "/O=openbmc-project.xyz/C=US/ST=CA/CN=|cn|"
    static void createSingleAuthority(const std::string& path,
                                      const std::string& cn)
    {
        std::string key = fs::path(path) / (cn + "_key");
        std::string cert = fs::path(path) / (cn + "_cert");
        std::string cmd = "openssl req -x509 -sha256 -newkey rsa:2048 -keyout ";
        cmd += key + " -out " + cert + " -nodes --days 365000 ";
        cmd += "-subj /O=openbmc-project.xyz/CN=" + cn;
        ASSERT_EQ(std::system(cmd.c_str()), 0);
    }

    // Appends the content of the |from| file to the |to| file.
    static void appendContentFromFile(const std::string& to,
                                      const std::string& from)
    {
        ASSERT_NO_THROW({
            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);
            inputCertFileStream.open(from);
            outputCertFileStream.open(to, std::ios::app);
            outputCertFileStream << inputCertFileStream.rdbuf() << std::flush;
            inputCertFileStream.close();
            outputCertFileStream.close();
        });
    }

    // Appends the content of the |from| buffer to the |to| file.
    static void setContentFromString(const std::string& to,
                                     const std::string& from)
    {
        ASSERT_NO_THROW({
            std::ofstream outputCertFileStream;
            outputCertFileStream.exceptions(std::ofstream::failbit |
                                            std::ofstream::badbit |
                                            std::ofstream::eofbit);
            outputCertFileStream.open(to, std::ios::out);
            outputCertFileStream << from << std::flush;
            outputCertFileStream.close();
        });
    }

    // Verifies the effect of InstallAll or ReplaceAll
    void verifyCertificates(std::vector<std::unique_ptr<Certificate>>& certs)
    {
        // The trust bundle file has been copied over
        EXPECT_FALSE(fs::is_empty(authoritiesListFolder));
        EXPECT_TRUE(
            compareFiles(authoritiesListFolder / defaultAuthoritiesListFileName,
                         sourceAuthoritiesListFile));

        ASSERT_EQ(certs.size(), maxNumAuthorityCertificates);
        // Check attributes and alias
        for (size_t i = 0; i < certs.size(); ++i)
        {
            std::string name = "root_" + std::to_string(i);
            EXPECT_EQ(certs[i]->subject(), "O=openbmc-project.xyz,CN=" + name);
            EXPECT_EQ(certs[i]->issuer(), "O=openbmc-project.xyz,CN=" + name);
            std::string symbolLink =
                authoritiesListFolder /
                (certs[i]->getCertId().substr(0, 8) + ".0");
            ASSERT_TRUE(fs::exists(symbolLink));
            compareFileAgainstString(symbolLink, certs[i]->certificateString());
        }
    }

    // Expects that the content of |path| file is |buffer|.
    static void compareFileAgainstString(const std::string& path,
                                         const std::string& buffer)
    {
        ASSERT_NO_THROW({
            std::ifstream inputCertFileStream;
            inputCertFileStream.exceptions(std::ifstream::failbit |
                                           std::ifstream::badbit |
                                           std::ifstream::eofbit);
            inputCertFileStream.open(path);
            std::stringstream read;
            read << inputCertFileStream.rdbuf();
            inputCertFileStream.close();
            EXPECT_EQ(read.str(), buffer);
        });
    };

    sdbusplus::bus::bus bus;
    fs::path authoritiesListFolder;
    fs::path sourceAuthoritiesListFile;
};

// Tests that the Authority Manager installs all the certificates in an
// authorities list
TEST_F(AuthoritiesListTest, InstallAll)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    ASSERT_TRUE(manager.getCertificates().empty());

    std::vector<sdbusplus::message::object_path> objects =
        manager.installAll(sourceAuthoritiesListFile);
    for (size_t i = 0; i < manager.getCertificates().size(); ++i)
    {
        EXPECT_EQ(manager.getCertificates()[i]->getObjectPath(), objects[i]);
    }
    verifyCertificates(manager.getCertificates());
}

// Tests that the Authority Manager recovers from the authorities list persisted
// in the installation path at boot up
TEST_F(AuthoritiesListTest, RecoverAtBootUp)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;
    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);

    // Copy the trust bundle into the installation path before creating an
    // Authority Manager
    fs::copy_file(/*from=*/sourceAuthoritiesListFile,
                  authoritiesListFolder / defaultAuthoritiesListFileName);
    // Create some noise as well
    fs::copy_file(/*from=*/sourceAuthoritiesListFile,
                  authoritiesListFolder / "should_be_deleted");

    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);

    ASSERT_EQ(manager.getCertificates().size(), maxNumAuthorityCertificates);

    // Check attributes and alias
    std::unordered_set<std::string> expectedFiles = {authoritiesListFolder /
                                                     "trust_bundle"};
    std::vector<std::unique_ptr<Certificate>>& certs =
        manager.getCertificates();
    for (size_t i = 0; i < certs.size(); ++i)
    {
        std::string name = "root_" + std::to_string(i);
        EXPECT_EQ(certs[i]->subject(), "O=openbmc-project.xyz,CN=" + name);
        EXPECT_EQ(certs[i]->issuer(), "O=openbmc-project.xyz,CN=" + name);
        std::string symbolLink =
            authoritiesListFolder / (certs[i]->getCertId().substr(0, 8) + ".0");
        expectedFiles.insert(symbolLink);
        expectedFiles.insert(certs[i]->getCertFilePath());
        ASSERT_TRUE(fs::exists(symbolLink));
        compareFileAgainstString(symbolLink, certs[i]->certificateString());
    }

    // Check folder content
    for (auto& path : fs::directory_iterator(authoritiesListFolder))
    {
        EXPECT_NE(path, authoritiesListFolder / "should_be_deleted");
        expectedFiles.erase(path.path());
    }
    EXPECT_TRUE(expectedFiles.empty());
}

TEST_F(AuthoritiesListTest, InstallAndDelete)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return())
        .WillOnce(Return());
    ASSERT_TRUE(manager.getCertificates().empty());
    ASSERT_EQ(manager.installAll(sourceAuthoritiesListFile).size(),
              maxNumAuthorityCertificates);
    manager.deleteAll();
    EXPECT_TRUE(manager.getCertificates().empty());
    // Check folder content
    for (const fs::path& f : fs::directory_iterator(authoritiesListFolder))
    {
        EXPECT_THAT(f.filename(), testing::AnyOf(".", ".."));
    }
}

TEST_F(AuthoritiesListTest, InstallAllWrongManagerType)
{
    std::string endpoint("ldap");
    CertificateType type = CertificateType::Server;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest serverManager(bus, event, object.c_str(), type, "",
                                authoritiesListFolder);
    EXPECT_THROW(serverManager.installAll(sourceAuthoritiesListFile),
                 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);

    type = CertificateType::Client;
    object = std::string(objectNamePrefix) + '/' +
             certificateTypeToString(type) + '/' + endpoint;
    ManagerInTest clientManager(bus, event, object.c_str(), type, "",
                                authoritiesListFolder);
    EXPECT_THROW(clientManager.installAll(sourceAuthoritiesListFile),
                 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
}

TEST_F(AuthoritiesListTest, InstallAllTwice)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return());
    ASSERT_TRUE(manager.getCertificates().empty());

    ASSERT_EQ(manager.installAll(sourceAuthoritiesListFile).size(),
              maxNumAuthorityCertificates);
    EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile).size(),
                 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
}

TEST_F(AuthoritiesListTest, InstallAllMissSourceFile)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);

    EXPECT_THROW(manager.installAll(authoritiesListFolder / "trust_bundle"),
                 InternalFailure);
}

TEST_F(AuthoritiesListTest, TooManyRootCertificates)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);
    createAuthoritiesList(maxNumAuthorityCertificates + 1);
    EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
                 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed);
}

TEST_F(AuthoritiesListTest, CertInWrongFormat)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);

    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);

    // Replace the authorities list with non-valid PEM encoded x509 certificate
    setContentFromString(sourceAuthoritiesListFile, "blah-blah");
    EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
                 InvalidCertificate);
    setContentFromString(sourceAuthoritiesListFile,
                         "-----BEGIN CERTIFICATE-----");
    EXPECT_THROW(manager.installAll(sourceAuthoritiesListFile),
                 InvalidCertificate);
}

TEST_F(AuthoritiesListTest, ReplaceAll)
{
    std::string endpoint("ldap");
    std::string verifyUnit(ManagerInTest::unitToRestartInTest);
    CertificateType type = CertificateType::Authority;

    std::string object = std::string(objectNamePrefix) + '/' +
                         certificateTypeToString(type) + '/' + endpoint;

    auto event = sdeventplus::Event::get_default();
    // Attach the bus to sd_event to service user requests
    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
    ManagerInTest manager(bus, event, object.c_str(), type, verifyUnit,
                          authoritiesListFolder);
    EXPECT_CALL(manager, reloadOrReset(Eq(ManagerInTest::unitToRestartInTest)))
        .WillOnce(Return())
        .WillOnce(Return());
    manager.installAll(sourceAuthoritiesListFile);

    // Replace the current list with a different list
    fs::remove_all(sourceAuthoritiesListFile.parent_path());
    createAuthoritiesList(maxNumAuthorityCertificates);
    std::vector<sdbusplus::message::object_path> objects =
        manager.replaceAll(sourceAuthoritiesListFile);

    for (size_t i = 0; i < manager.getCertificates().size(); ++i)
    {
        EXPECT_EQ(manager.getCertificates()[i]->getObjectPath(), objects[i]);
    }
    verifyCertificates(manager.getCertificates());
}

} // namespace
} // namespace phosphor::certs
