/*
 *
 *    Copyright (c) 2021-2022 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      This file implements utility functions for OpenSSL, base-64
 *      encoding and decoding, date and time parsing, integer parsing,
 *      OID translation, and file reading.
 *
 */

#include "chip-cert.h"

#include <memory>
#include <utility>

#include <errno.h>
#include <lib/core/CHIPEncoding.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/SafeInt.h>

using namespace chip;
using namespace chip::Credentials;
using namespace chip::Encoding;
using namespace chip::ASN1;

int gNIDChipNodeId;
int gNIDChipFirmwareSigningId;
int gNIDChipICAId;
int gNIDChipVidVerificationSignerId;
int gNIDChipRootId;
int gNIDChipFabricId;
int gNIDChipCASEAuthenticatedTag;
int gNIDChipAttAttrVID;
int gNIDChipAttAttrPID;
int gNIDChipCurveP256 = EC_curve_nist2nid("P-256");

bool InitOpenSSL()
{
    bool res = true;

    OPENSSL_malloc_init();

    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();

    // TODO(#39306) Rename a lot of ChipXxx to MatterXxx.
    gNIDChipNodeId = OBJ_create("1.3.6.1.4.1.37244.1.1", "ChipNodeId", "ChipNodeId");
    if (gNIDChipNodeId == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipFirmwareSigningId = OBJ_create("1.3.6.1.4.1.37244.1.2", "ChipFirmwareSigningId", "ChipFirmwareSigningId");
    if (gNIDChipFirmwareSigningId == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipICAId = OBJ_create("1.3.6.1.4.1.37244.1.3", "ChipICAId", "ChipICAId");
    if (gNIDChipICAId == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipRootId = OBJ_create("1.3.6.1.4.1.37244.1.4", "ChipRootId", "ChipRootId");
    if (gNIDChipRootId == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipFabricId = OBJ_create("1.3.6.1.4.1.37244.1.5", "ChipFabricId", "ChipFabricId");
    if (gNIDChipFabricId == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipCASEAuthenticatedTag = OBJ_create("1.3.6.1.4.1.37244.1.6", "ChipCASEAuthenticatedTag", "ChipCASEAuthenticatedTag");
    if (gNIDChipCASEAuthenticatedTag == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipVidVerificationSignerId =
        OBJ_create("1.3.6.1.4.1.37244.1.7", "ChipVidVerificationSignerId", "ChipVidVerificationSignerId");
    if (gNIDChipVidVerificationSignerId == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipAttAttrVID = OBJ_create("1.3.6.1.4.1.37244.2.1", "ChipAttestationAttrVID", "ChipAttestationAttrVID");
    if (gNIDChipAttAttrVID == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    gNIDChipAttAttrPID = OBJ_create("1.3.6.1.4.1.37244.2.2", "ChipAttestationAttrPID", "ChipAttestationAttrPID");
    if (gNIDChipAttAttrPID == 0)
    {
        ReportOpenSSLErrorAndExit("OBJ_create", res = false);
    }

    ASN1_STRING_TABLE_add(gNIDChipNodeId, 16, 16, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipFirmwareSigningId, 16, 16, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipICAId, 16, 16, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipVidVerificationSignerId, 16, 16, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipRootId, 16, 16, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipFabricId, 16, 16, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipCASEAuthenticatedTag, 8, 8, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipAttAttrVID, 4, 4, B_ASN1_UTF8STRING, 0);
    ASN1_STRING_TABLE_add(gNIDChipAttAttrPID, 4, 4, B_ASN1_UTF8STRING, 0);

exit:
    return res;
}

bool IsChipCertFormat(CertFormat certFormat)
{
    return ((certFormat == kCertFormat_Chip_Raw) || (certFormat == kCertFormat_Chip_Base64) ||
            (certFormat == kCertFormat_Chip_Hex));
}

bool IsX509PrivateKeyFormat(KeyFormat keyFormat)
{
    return ((keyFormat == kKeyFormat_X509_PEM) || (keyFormat == kKeyFormat_X509_DER) || (keyFormat == kKeyFormat_X509_Hex));
}

bool IsChipPrivateKeyFormat(KeyFormat keyFormat)
{
    return ((keyFormat == kKeyFormat_Chip_Raw) || (keyFormat == kKeyFormat_Chip_Base64) || (keyFormat == kKeyFormat_Chip_Hex));
}

bool IsPrivateKeyFormat(KeyFormat keyFormat)
{
    return (IsX509PrivateKeyFormat(keyFormat) || IsChipPrivateKeyFormat(keyFormat));
}

bool IsChipPublicKeyFormat(KeyFormat keyFormat)
{
    return ((keyFormat == kKeyFormat_Chip_Pubkey_Raw) || (keyFormat == kKeyFormat_Chip_Pubkey_Base64) ||
            (keyFormat == kKeyFormat_Chip_Pubkey_Hex));
}

bool IsPublicKeyFormat(KeyFormat keyFormat)
{
    return (IsChipPublicKeyFormat(keyFormat) || (keyFormat == kKeyFormat_X509_Pubkey_PEM));
}

bool Base64Encode(const uint8_t * inData, uint32_t inDataLen, uint8_t * outBuf, uint32_t outBufSize, uint32_t & outDataLen)
{
    bool res = true;

    VerifyOrExit(outBuf != nullptr, res = false);
    VerifyOrExit(outBufSize >= BASE64_ENCODED_LEN(inDataLen), res = false);

    outDataLen = chip::Base64Encode32(inData, inDataLen, Uint8::to_char(outBuf));

exit:
    return res;
}

bool Base64Decode(const uint8_t * inData, uint32_t inDataLen, uint8_t * outBuf, uint32_t outBufSize, uint32_t & outDataLen)
{
    bool res = true;

    VerifyOrExit(outBuf != nullptr, res = false);
    VerifyOrExit(outBufSize >= BASE64_MAX_DECODED_LEN(inDataLen), res = false);

    outDataLen = chip::Base64Decode32(Uint8::to_const_char(inData), inDataLen, outBuf);
    VerifyOrExit(outDataLen != UINT32_MAX, res = false);

exit:
    return res;
}

bool IsBase64String(const char * str, uint32_t strLen)
{
    for (; strLen > 0; strLen--, str++)
    {
        if (!isalnum(*str) && *str != '+' && *str != '/' && *str != '=' && !isspace(*str))
        {
            return false;
        }
    }
    return true;
}

bool ContainsPEMMarker(const char * marker, const uint8_t * data, uint32_t dataLen)
{
    size_t markerLen = strlen(marker);

    if (dataLen > markerLen)
    {
        for (uint32_t i = 0; i <= dataLen - markerLen; i++)
        {
            if (strncmp(reinterpret_cast<char *>(const_cast<uint8_t *>(data + i)), marker, markerLen) == 0)
            {
                return true;
            }
        }
    }
    return false;
}

bool ParseDateTime(const char * str, struct tm & date)
{
    const char * p;

    memset(&date, 0, sizeof(date));

    if ((p = strptime(str, "%Y-%m-%d %H:%M:%S", &date)) == nullptr && (p = strptime(str, "%Y/%m/%d %H:%M:%S", &date)) == nullptr &&
        (p = strptime(str, "%Y%m%d%H%M%SZ", &date)) == nullptr && (p = strptime(str, "%Y-%m-%d", &date)) == nullptr &&
        (p = strptime(str, "%Y/%m/%d", &date)) == nullptr && (p = strptime(str, "%Y%m%d", &date)) == nullptr)
    {
        return false;
    }

    if (*p != 0)
    {
        return false;
    }

    return true;
}

bool OpenFile(const char * fileName, FILE *& file, bool toWrite)
{
    VerifyOrReturnError(fileName != nullptr, false);

    if (strcmp(fileName, "-") != 0)
    {
        file = fopen(fileName, toWrite ? "w+" : "r");
        if (file == nullptr)
        {
            fprintf(stderr, "Unable to open %s: %s\n", fileName, strerror(errno));
            return false;
        }
    }
    else
    {
        file = toWrite ? stdout : stdin;
    }

    return true;
}

void CloseFile(FILE *& file)
{
    if (file != nullptr)
    {
        fclose(file);
        file = nullptr;
    }
}

bool ReadFileIntoMem(const char * fileName, uint8_t * data, uint32_t & dataLen)
{
    bool res    = true;
    FILE * file = nullptr;
    long int fileLen;
    size_t readRes;

    res = OpenFile(fileName, file, false);
    VerifyTrueOrExit(res);

    fseek(file, 0, SEEK_END);
    fileLen = ftell(file);
    fseek(file, 0, SEEK_SET);
    if (fileLen < 0 || ferror(file))
    {
        fprintf(stderr, "Error reading %s: %s\n", fileName, strerror(errno));
        ExitNow(res = false);
    }

    VerifyOrExit(chip::CanCastTo<uint32_t>(fileLen), res = false);

    dataLen = static_cast<uint32_t>(fileLen);

    if (data != nullptr)
    {
        readRes = fread(data, 1, static_cast<size_t>(dataLen), file);
        if (readRes < static_cast<size_t>(dataLen) || ferror(file))
        {
            fprintf(stderr, "Error reading %s: %s\n", fileName, strerror(errno));
            ExitNow(res = false);
        }
    }

exit:
    CloseFile(file);
    return res;
}

bool WriteDataIntoFile(const char * fileName, const uint8_t * data, size_t dataLen, DataFormat dataFmt)
{
    bool res                    = true;
    FILE * file                 = nullptr;
    const uint8_t * dataToWrite = nullptr;
    uint32_t dataToWriteLen     = 0;
    std::unique_ptr<uint8_t[]> dataBuf;

    VerifyOrExit(OpenFile(fileName, file, true) == true, res = false);
    VerifyOrExit(data != nullptr, res = false);
    VerifyOrExit(dataFmt != kDataFormat_Unknown, res = false);

    if (dataFmt == kDataFormat_Base64)
    {
        VerifyOrExit(CanCastTo<uint32_t>(BASE64_ENCODED_LEN(dataLen)), res = false);
        dataToWriteLen = static_cast<uint32_t>(BASE64_ENCODED_LEN(dataLen));
        dataBuf        = std::make_unique<uint8_t[]>(dataToWriteLen);
        dataToWrite    = dataBuf.get();

        VerifyOrExit(Base64Encode(data, static_cast<uint32_t>(dataLen), dataBuf.get(), dataToWriteLen, dataToWriteLen),
                     res = false);
    }
    else if (dataFmt == kDataFormat_Hex)
    {
        VerifyOrExit(CanCastTo<uint32_t>(HEX_ENCODED_LENGTH(dataLen)), res = false);
        dataToWriteLen = static_cast<uint32_t>(HEX_ENCODED_LENGTH(dataLen));
        dataBuf        = std::make_unique<uint8_t[]>(dataToWriteLen);
        dataToWrite    = dataBuf.get();

        VerifyOrExit(BytesToHex(data, dataLen, Uint8::to_char(dataBuf.get()), dataToWriteLen, HexFlags::kUppercase) ==
                         CHIP_NO_ERROR,
                     res = false);
    }
    else
    {
        VerifyOrExit(CanCastTo<uint32_t>(dataLen), res = false);
        dataToWriteLen = static_cast<uint32_t>(dataLen);
        dataToWrite    = data;
    }

    if (fwrite(dataToWrite, 1, dataToWriteLen, file) != dataToWriteLen)
    {
        fprintf(stderr, "Unable to write to %s: %s\n", fileName, strerror(ferror(file) ? errno : ENOSPC));
        ExitNow(res = false);
    }

    // Add new line if the output is to stdout in a text format
    if ((strcmp(fileName, "-") == 0) && (dataFmt != kDataFormat_Raw) && (fwrite("\n", 1, 1, file) != 1))
    {
        fprintf(stderr, "Unable to write to %s: %s\n", fileName, strerror(ferror(file) ? errno : ENOSPC));
        ExitNow(res = false);
    }

exit:
    CloseFile(file);
    return res;
}
