// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright OpenBMC Authors
#include "mutual_tls.hpp"

#include "bmcweb_config.h"

#include "identity.hpp"
#include "mutual_tls_private.hpp"
#include "sessions.hpp"

#include <bit>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>

extern "C"
{
#include <openssl/asn1.h>
#include <openssl/obj_mac.h>
#include <openssl/objects.h>
#include <openssl/types.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/x509v3.h>
}

#include "logging.hpp"

#include <boost/asio/ip/address.hpp>
#include <boost/asio/ssl/verify_context.hpp>

#include <memory>
#include <string_view>

std::string getCommonNameFromCert(X509* cert)
{
    std::string commonName;
    // Extract username contained in CommonName
    commonName.resize(256, '\0');
    int length = X509_NAME_get_text_by_NID(
        X509_get_subject_name(cert), NID_commonName, commonName.data(),
        static_cast<int>(commonName.size()));
    if (length <= 0)
    {
        BMCWEB_LOG_DEBUG("TLS cannot get common name to create session");
        return "";
    }
    commonName.resize(static_cast<size_t>(length));
    return commonName;
}

bool isUPNMatch(std::string_view upn, std::string_view hostname)
{
    // UPN format: <username>@<domain> (e.g. user@domain.com)
    // https://learn.microsoft.com/en-us/windows/win32/ad/naming-properties#userprincipalname
    size_t upnDomainPos = upn.find('@');
    if (upnDomainPos == std::string_view::npos)
    {
        return false;
    }

    // The hostname should match the domain part of the UPN
    std::string_view upnDomain = upn.substr(upnDomainPos + 1);
    while (true)
    {
        std::string_view upnDomainMatching = upnDomain;
        size_t dotUPNPos = upnDomain.find_last_of('.');
        if (dotUPNPos != std::string_view::npos)
        {
            upnDomainMatching = upnDomain.substr(dotUPNPos + 1);
        }

        std::string_view hostDomainMatching = hostname;
        size_t dotHostPos = hostname.find_last_of('.');
        if (dotHostPos != std::string_view::npos)
        {
            hostDomainMatching = hostname.substr(dotHostPos + 1);
        }

        if (upnDomainMatching != hostDomainMatching)
        {
            return false;
        }

        if (dotUPNPos == std::string_view::npos)
        {
            return true;
        }

        upnDomain = upnDomain.substr(0, dotUPNPos);
        hostname = hostname.substr(0, dotHostPos);
    }
}

std::string getUPNFromCert(X509* peerCert, std::string_view hostname)
{
    GENERAL_NAMES* gs = static_cast<GENERAL_NAMES*>(
        X509_get_ext_d2i(peerCert, NID_subject_alt_name, nullptr, nullptr));
    if (gs == nullptr)
    {
        return "";
    }

    std::string ret;
    for (int i = 0; i < sk_GENERAL_NAME_num(gs); i++)
    {
        GENERAL_NAME* g = sk_GENERAL_NAME_value(gs, i);
        if (g->type != GEN_OTHERNAME)
        {
            continue;
        }

        // NOLINTBEGIN(cppcoreguidelines-pro-type-union-access)
        int nid = OBJ_obj2nid(g->d.otherName->type_id);
        if (nid != NID_ms_upn)
        {
            continue;
        }

        int type = g->d.otherName->value->type;
        if (type != V_ASN1_UTF8STRING)
        {
            continue;
        }

        char* upnChar =
            std::bit_cast<char*>(g->d.otherName->value->value.utf8string->data);
        unsigned int upnLen = static_cast<unsigned int>(
            g->d.otherName->value->value.utf8string->length);
        // NOLINTEND(cppcoreguidelines-pro-type-union-access)

        std::string upn = std::string(upnChar, upnLen);
        if (!isUPNMatch(upn, hostname))
        {
            continue;
        }

        size_t upnDomainPos = upn.find('@');
        ret = upn.substr(0, upnDomainPos);
        break;
    }
    GENERAL_NAMES_free(gs);
    return ret;
}

std::string getUsernameFromCert(X509* cert)
{
    const persistent_data::AuthConfigMethods& authMethodsConfig =
        persistent_data::SessionStore::getInstance().getAuthMethodsConfig();
    switch (authMethodsConfig.mTLSCommonNameParsingMode)
    {
        case persistent_data::MTLSCommonNameParseMode::Invalid:
        case persistent_data::MTLSCommonNameParseMode::Whole:
        {
            // Not yet supported
            return "";
        }
        case persistent_data::MTLSCommonNameParseMode::UserPrincipalName:
        {
            std::string hostname = getHostName();
            if (hostname.empty())
            {
                BMCWEB_LOG_WARNING("Failed to get hostname");
                return "";
            }
            return getUPNFromCert(cert, hostname);
        }
        case persistent_data::MTLSCommonNameParseMode::CommonName:
        {
            return getCommonNameFromCert(cert);
        }
        default:
        {
            return "";
        }
    }
}

std::shared_ptr<persistent_data::UserSession> verifyMtlsUser(
    const boost::asio::ip::address& clientIp,
    boost::asio::ssl::verify_context& ctx)
{
    // do nothing if TLS is disabled
    if (!persistent_data::SessionStore::getInstance()
             .getAuthMethodsConfig()
             .tls)
    {
        BMCWEB_LOG_DEBUG("TLS auth_config is disabled");
        return nullptr;
    }

    X509_STORE_CTX* cts = ctx.native_handle();
    if (cts == nullptr)
    {
        BMCWEB_LOG_DEBUG("Cannot get native TLS handle.");
        return nullptr;
    }

    // Get certificate
    X509* peerCert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
    if (peerCert == nullptr)
    {
        BMCWEB_LOG_DEBUG("Cannot get current TLS certificate.");
        return nullptr;
    }

    // Check if certificate is OK
    int ctxError = X509_STORE_CTX_get_error(cts);
    if (ctxError != X509_V_OK)
    {
        BMCWEB_LOG_INFO("Last TLS error is: {}", ctxError);
        return nullptr;
    }

    // Check that we have reached final certificate in chain
    int32_t depth = X509_STORE_CTX_get_error_depth(cts);
    if (depth != 0)
    {
        BMCWEB_LOG_DEBUG(
            "Certificate verification in progress (depth {}), waiting to reach final depth",
            depth);
        return nullptr;
    }

    BMCWEB_LOG_DEBUG("Certificate verification of final depth");

    if (X509_check_purpose(peerCert, X509_PURPOSE_SSL_CLIENT, 0) != 1)
    {
        BMCWEB_LOG_DEBUG(
            "Chain does not allow certificate to be used for SSL client authentication");
        return nullptr;
    }

    std::string sslUser = getUsernameFromCert(peerCert);
    if (sslUser.empty())
    {
        BMCWEB_LOG_WARNING("Failed to get user from peer certificate");
        return nullptr;
    }

    std::string unsupportedClientId;
    return persistent_data::SessionStore::getInstance().generateUserSession(
        sslUser, clientIp, unsupportedClientId,
        persistent_data::SessionType::MutualTLS);
}
