/*
 *
 *    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 the command handler for the 'chip-cert' tool
 *      that re-signs a CHIP certificate.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include "chip-cert.h"

namespace {

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

#define CMD_NAME "chip-cert resign-cert"

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg);

// clang-format off
OptionDef gCmdOptionDefs[] =
{
    { "cert",       kArgumentRequired, 'c' },
    { "out",        kArgumentRequired, 'o' },
    { "ca-cert",    kArgumentRequired, 'C' },
    { "ca-key",     kArgumentRequired, 'K' },
    { "self",       kNoArgument,       's' },
    { }
};

const char * const gCmdOptionHelp =
    "  -c, --cert <file/str>\n"
    "\n"
    "       File or string containing the certificate to be re-signed.\n"
    "\n"
    "  -o, --out <file/stdout>\n"
    "\n"
    "       File to contain the re-signed certificate.\n"
    "       If specified '-' then output is written to stdout.\n"
    "\n"
    "  -C, --ca-cert <file/str>\n"
    "\n"
    "       File or string containing CA certificate to be used to re-sign the certificate.\n"
    "\n"
    "  -K, --ca-key <file/str>\n"
    "\n"
    "       File or string containing CA private key to be used to re-sign the certificate.\n"
    "\n"
    "  -s, --self\n"
    "\n"
    "       Generate a self-signed certificate.\n"
    "\n"
    ;

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

HelpOptions gHelpOptions(
    CMD_NAME,
    "Usage: " CMD_NAME " [ <options...> ]\n",
    CHIP_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Resign a CHIP certificate using a new CA certificate/key."
);

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

const char * gInCertFileNameOrStr = nullptr;
const char * gOutCertFileName     = nullptr;
const char * gCACertFileNameOrStr = nullptr;
const char * gCAKeyFileNameOrStr  = nullptr;
bool gSelfSign                    = false;

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    switch (id)
    {
    case 'c':
        gInCertFileNameOrStr = arg;
        break;
    case 'o':
        gOutCertFileName = arg;
        break;
    case 'C':
        gCACertFileNameOrStr = arg;
        break;
    case 'K':
        gCAKeyFileNameOrStr = arg;
        break;
    case 's':
        gSelfSign = true;
        break;
    default:
        PrintArgError("%s: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

} // namespace

bool Cmd_ResignCert(int argc, char * argv[])
{
    bool res = true;
    CertFormat inCertFmt;
    std::unique_ptr<X509, void (*)(X509 *)> cert(X509_new(), &X509_free);
    std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY *)> caKey(EVP_PKEY_new(), &EVP_PKEY_free);

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

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

    if (gInCertFileNameOrStr == nullptr)
    {
        fprintf(stderr, "Please specify certificate to be resigned using --cert option.\n");
        ExitNow(res = false);
    }

    if (gOutCertFileName == nullptr)
    {
        fprintf(stderr, "Please specify the file name for the new certificate using the --out option.\n");
        ExitNow(res = false);
    }

    if (gCACertFileNameOrStr == nullptr && !gSelfSign)
    {
        fprintf(stderr,
                "Please specify a CA certificate to be used to sign the new certificate (using\n"
                "the --ca-cert option) or --self to generate a self-signed certificate.\n");
        ExitNow(res = false);
    }
    else if (gCACertFileNameOrStr != nullptr && gSelfSign)
    {
        fprintf(stderr, "Please specify only one of --ca-cert and --self.\n");
        ExitNow(res = false);
    }

    if (gCAKeyFileNameOrStr == nullptr)
    {
        fprintf(stderr, "Please specify the CA key using the --ca-key option.\n");
        ExitNow(res = false);
    }

    if (access(gOutCertFileName, R_OK) == 0)
    {
        fprintf(stderr,
                "Output certificate file already exists (%s)\n"
                "To replace the file, please remove it and re-run the command.\n",
                gOutCertFileName);
        ExitNow(res = false);
    }

    res = InitOpenSSL();
    VerifyTrueOrExit(res);

    res = ReadCert(gInCertFileNameOrStr, cert.get(), inCertFmt);
    VerifyTrueOrExit(res);

    res = ReadKey(gCAKeyFileNameOrStr, caKey);
    VerifyTrueOrExit(res);

    if (!gSelfSign)
    {
        std::unique_ptr<X509, void (*)(X509 *)> caCert(X509_new(), &X509_free);

        res = ReadCert(gCACertFileNameOrStr, caCert.get());
        VerifyTrueOrExit(res);

        res = ResignCert(cert.get(), caCert.get(), caKey.get());
        VerifyTrueOrExit(res);
    }
    else
    {
        res = ResignCert(cert.get(), cert.get(), caKey.get());
        VerifyTrueOrExit(res);
    }

    res = WriteCert(gOutCertFileName, cert.get(), inCertFmt);
    VerifyTrueOrExit(res);

exit:
    return res;
}
