/*
 *
 *    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 <file/stdout>\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...>] <file/str>\n",
    CHIP_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Print a CHIP operational certificate.\n"
    "\n"
    "ARGUMENTS\n"
    "\n"
    "  <file/str>\n"
    "\n"
    "       File or string containing a CHIP certificate.\n"
    "\n"
);

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

const char * gInFileNameOrStr = 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;
    }

    gInFileNameOrStr = 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(gInFileNameOrStr, cert.get());
    VerifyTrueOrExit(res);

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

exit:
    return res;
}
