/*
 *
 *    Copyright (c) 2021 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 the command handler for the 'chip-cert' tool
 *      that prints the contents of a CHIP certificate.
 *
 */

#include "chip-cert.h"

namespace {

using namespace chip;
using namespace chip::ArgParser;
using namespace chip::Credentials;
using namespace chip::ASN1;

#define CMD_NAME "chip-cert print-cert"

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg);
bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[]);

// clang-format off
OptionDef gCmdOptionDefs[] =
{
    { "out",           kArgumentRequired, 'o' },
    { }
};

const char * const gCmdOptionHelp =
    "   -o, --out\n"
    "\n"
    "       The output printed certificate file name. If not specified\n"
    "       or if specified - then output is written to stdout.\n"
    "\n"
    ;

OptionSet gCmdOptions =
{
    HandleOption,
    gCmdOptionDefs,
    "COMMAND OPTIONS",
    gCmdOptionHelp
};

HelpOptions gHelpOptions(
    CMD_NAME,
    "Usage: " CMD_NAME " [<options...>] <cert-file>\n",
    CHIP_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Print a CHIP certificate.\n"
    "\n"
    "ARGUMENTS\n"
    "\n"
    "  <cert-file>\n"
    "\n"
    "       A file containing a CHIP certificate.\n"
    "\n"
);

OptionSet *gCmdOptionSets[] =
{
    &gCmdOptions,
    &gHelpOptions,
    nullptr
};
// clang-format on

const char * gInFileName  = nullptr;
const char * gOutFileName = "-";

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    switch (id)
    {
    case 'o':
        gOutFileName = arg;
        break;
    default:
        PrintArgError("%s: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[])
{
    if (argc == 0)
    {
        PrintArgError("%s: Please specify the name of the certificate to be printed.\n", progName);
        return false;
    }

    if (argc > 1)
    {
        PrintArgError("%s: Unexpected argument: %s\n", progName, argv[1]);
        return false;
    }

    gInFileName = argv[0];

    return true;
}

void Indent(FILE * file, int count)
{
    while (count--)
    {
        fputc(' ', file);
    }
}

void PrintHexField(FILE * file, const char * name, int indent, size_t count, const uint8_t * data, size_t countPerRow = 16)
{
    Indent(file, indent);
    indent += fprintf(file, "%s: ", name);

    for (size_t i = 0; i < count; i++)
    {
        if (i != 0 && i != count && i % countPerRow == 0)
        {
            fprintf(file, "\n");
            Indent(file, indent);
        }

        fprintf(file, "%02X ", data[i]);
    }

    fprintf(file, "\n");
}

void PrintEpochTime(FILE * file, const char * name, int indent, uint32_t epochTime)
{
    chip::ASN1::ASN1UniversalTime asn1Time;

    ChipEpochToASN1Time(epochTime, asn1Time);

    Indent(file, indent);
    fprintf(file, "%s: ", name);

    fprintf(file, "0x%08" PRIX32 "  ( %04d/%02d/%02d %02d:%02d:%02d )\n", epochTime, asn1Time.Year, asn1Time.Month, asn1Time.Day,
            asn1Time.Hour, asn1Time.Minute, asn1Time.Second);
}

void PrintDN(FILE * file, const char * name, int indent, const ChipDN * dn)
{
    uint8_t rdnCount = dn->RDNCount();
    char valueStr[128];

    Indent(file, indent);
    indent += fprintf(file, "%s: [[ ", name);

    for (uint8_t i = 0; i < rdnCount; i++)
    {
        if (IsChip64bitDNAttr(dn->rdn[i].mAttrOID))
        {
            snprintf(valueStr, sizeof(valueStr), "%016" PRIX64, dn->rdn[i].mChipVal);
        }
        else if (IsChip32bitDNAttr(dn->rdn[i].mAttrOID))
        {
            snprintf(valueStr, sizeof(valueStr), "%08" PRIX32, static_cast<uint32_t>(dn->rdn[i].mChipVal));
        }
        else
        {
            size_t len = dn->rdn[i].mString.size();
            if (len > sizeof(valueStr) - 1)
            {
                len = sizeof(valueStr) - 1;
            }
            memcpy(valueStr, dn->rdn[i].mString.data(), len);
            valueStr[len] = 0;
        }

        fprintf(file, "%s = %s", chip::ASN1::GetOIDName(dn->rdn[i].mAttrOID), valueStr);
        if (i == rdnCount - 1)
        {
            fprintf(file, " ]]\n");
        }
        else
        {
            fprintf(file, ",\n");
            Indent(file, indent);
        }
    }
}

bool PrintCert(const char * fileName, X509 * cert)
{
    bool res       = true;
    CHIP_ERROR err = CHIP_NO_ERROR;
    FILE * file    = nullptr;
    ChipCertificateSet certSet;
    const ChipCertificateData * certData;
    chip::BitFlags<CertDecodeFlags> decodeFlags;
    uint8_t chipCertBuf[kMaxCHIPCertLength];
    MutableByteSpan chipCert(chipCertBuf);
    int indent = 4;

    VerifyOrExit(cert != nullptr, res = false);

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

    res = X509ToChipCert(cert, chipCert);
    VerifyTrueOrExit(res);

    err = certSet.Init(1);
    if (err != CHIP_NO_ERROR)
    {
        fprintf(stderr, "Failed to initialize certificate set: %s\n", chip::ErrorStr(err));
        ExitNow(res = false);
    }

    err = certSet.LoadCert(chipCert, decodeFlags);
    if (err != CHIP_NO_ERROR)
    {
        fprintf(stderr, "Error reading %s: %s\n", fileName, chip::ErrorStr(err));
        ExitNow(res = false);
    }

    certData = certSet.GetLastCert();

    fprintf(file, "CHIP Certificate:\n");

    Indent(file, indent);
    fprintf(file, "Signature Algo  : %s\n", GetOIDName(certData->mSigAlgoOID));

    PrintDN(file, "Issuer          ", indent, &certData->mIssuerDN);

    PrintEpochTime(file, "Not Before      ", indent, certData->mNotBeforeTime);

    PrintEpochTime(file, "Not After       ", indent, certData->mNotAfterTime);

    PrintDN(file, "Subject         ", indent, &certData->mSubjectDN);

    Indent(file, indent);
    fprintf(file, "Public Key Algo : %s\n", GetOIDName(certData->mPubKeyAlgoOID));

    Indent(file, indent);
    fprintf(file, "Curve Id        : %s\n", GetOIDName(certData->mPubKeyCurveOID));

    PrintHexField(file, "Public Key      ", indent, certData->mPublicKey.size(), certData->mPublicKey.data());

    Indent(file, indent);
    fprintf(file, "Extensions:\n");

    indent += 4;
    if (certData->mCertFlags.Has(CertFlags::kIsCA))
    {
        Indent(file, indent);
        fprintf(file, "Is CA            : true\n");
    }

    if (certData->mCertFlags.Has(CertFlags::kPathLenConstraintPresent))
    {
        Indent(file, indent);
        fprintf(file, "Path Length Const: %u\n", (unsigned) certData->mPathLenConstraint);
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_KeyUsage))
    {
        Indent(file, indent);
        fprintf(file, "Key Usage        : ");
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kDigitalSignature))
        {
            fprintf(file, "DigitalSignature ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kNonRepudiation))
        {
            fprintf(file, "NonRepudiation ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kKeyEncipherment))
        {
            fprintf(file, "KeyEncipherment ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kDataEncipherment))
        {
            fprintf(file, "DataEncipherment ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kKeyAgreement))
        {
            fprintf(file, "KeyAgreement ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kKeyCertSign))
        {
            fprintf(file, "KeyCertSign ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kCRLSign))
        {
            fprintf(file, "CRLSign ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kEncipherOnly))
        {
            fprintf(file, "EncipherOnly ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kDecipherOnly))
        {
            fprintf(file, "DecipherOnly ");
        }
        fprintf(file, "\n");
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_ExtendedKeyUsage))
    {
        Indent(file, indent);
        fprintf(file, "Key Purpose      : ");
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kServerAuth))
        {
            fprintf(file, "ServerAuth ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kClientAuth))
        {
            fprintf(file, "ClientAuth ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kCodeSigning))
        {
            fprintf(file, "CodeSigning ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kEmailProtection))
        {
            fprintf(file, "EmailProtection ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kTimeStamping))
        {
            fprintf(file, "TimeStamping ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kOCSPSigning))
        {
            fprintf(file, "OCSPSigning ");
        }
        fprintf(file, "\n");
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_SubjectKeyId))
    {
        PrintHexField(file, "Subject Key Id   ", indent, certData->mSubjectKeyId.size(), certData->mSubjectKeyId.data(),
                      certData->mSubjectKeyId.size());
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_AuthKeyId))
    {
        PrintHexField(file, "Authority Key Id ", indent, certData->mAuthKeyId.size(), certData->mAuthKeyId.data(),
                      certData->mAuthKeyId.size());
    }

    indent -= 4;
    PrintHexField(file, "Signature       ", indent, certData->mSignature.size(), certData->mSignature.data());

exit:
    CloseFile(file);
    return res;
}

} // namespace

bool Cmd_PrintCert(int argc, char * argv[])
{
    bool res = true;
    std::unique_ptr<X509, void (*)(X509 *)> cert(X509_new(), &X509_free);

    if (argc == 1)
    {
        gHelpOptions.PrintBriefUsage(stderr);
        ExitNow(res = true);
    }

    res = ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets, HandleNonOptionArgs);
    VerifyTrueOrExit(res);

    res = ReadCert(gInFileName, cert.get());
    VerifyTrueOrExit(res);

    res = PrintCert(gOutFileName, cert.get());
    VerifyTrueOrExit(res);

exit:
    return res;
}
