/*
 *
 *    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 'weave' tool
 *      that generates a Weave device certificate.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>

#include "weave-tool.h"

using namespace nl::Weave::Profiles::Security;
using namespace nl::Weave::ASN1;

#define CMD_NAME "weave gen-device-cert"

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

static OptionDef gCmdOptionDefs[] =
{
    { "dev-id",     kArgumentRequired, 'i' },
    { "key",        kArgumentRequired, 'k' },
    { "ca-cert",    kArgumentRequired, 'C' },
    { "ca-key",     kArgumentRequired, 'K' },
    { "out",        kArgumentRequired, 'o' },
    { "out-key",    kArgumentRequired, 'O' },
    { "curve",      kArgumentRequired, 'u' },
    { "valid-from", kArgumentRequired, 'V' },
    { "lifetime",   kArgumentRequired, 'l' },
    { "sha1",       kNoArgument,       '1' },
    { "sha256",     kNoArgument,       '2' },
    { NULL }
};

static const char *const gCmdOptionHelp =
    "   -i, --dev-id <hex-digits>\n"
    "\n"
    "       The device id (in hex) for which the certificate should be generated.\n"
    "\n"
    "   -C, --ca-cert <file>\n"
    "\n"
    "       File containing CA certificate to be used to sign the device certificate\n"
    "       (in PEM format).\n"
    "\n"
    "   -K, --ca-key <file>\n"
    "\n"
    "       File containing CA private key to be used to sign the device certificate\n"
    "       (in PEM format).\n"
    "\n"
    "   -k, --key <file>\n"
    "\n"
    "       File containing the public and private keys for the new certificate (in\n"
    "       PEM format). If not specified, a new key pair will be generated.\n"
    "\n"
    "   -o, --out <file>\n"
    "\n"
    "       File to contain the new device certificate. (Will be written in Weave base-64\n"
    "       format).\n"
    "\n"
    "   -O, --out-key <file>\n"
    "\n"
    "       File to contain the public/private for the new device certificate (in Weave\n"
    "       base-64 format). This option must be specified if the --key option is not.\n"
    "\n"
    "   -V, --valid-from <YYYY>-<MM>-<DD> [ <HH>:<MM>:<SS> ]\n"
    "\n"
    "       The start date for the certificate's validity period.  If not specified,\n"
    "       the validity period starts on the current day.\n"
    "\n"
    "   -l, --lifetime <days>\n"
    "\n"
    "       The lifetime for the new certificate, in whole days.\n"
    "\n"
    "   -u, --curve <elliptic-curve-name>\n"
    "\n"
    "       The elliptic curve to use when generating the public/private keys. This option\n"
    "       must be specified if the --key option is not given.\n"
    "\n"
    "   -1, --sha1\n"
    "\n"
    "       Sign the certificate using a SHA-1 hash.\n"
    "\n"
    "   -2, --sha256\n"
    "\n"
    "       Sign the certificate using a SHA-256 hash.\n"
    "\n"
    ;

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

static HelpOptions gHelpOptions(
    CMD_NAME,
    "Usage: " CMD_NAME " [ <options...> ]\n",
    WEAVE_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Generate a Weave device certificate"
);

static OptionSet *gCmdOptionSets[] =
{
    &gCmdOptions,
    &gHelpOptions,
    NULL
};

static uint64_t gDevId = 0;
static const char *gCurveName = NULL;
static const char *gCACertFileName = NULL;
static const char *gCAKeyFileName = NULL;
static const char *gInCertKeyFileName = NULL;
static const char *gOutCertFileName = NULL;
static const char *gOutKeyFileName = NULL;
static int32_t gValidDays = 0;
static const EVP_MD *gSigHashAlgo = NULL;
static struct tm gValidFrom;

bool Cmd_GenDeviceCert(int argc, char *argv[])
{
    bool res = true;
    int curveNID = 0;
    FILE *outCertFile = NULL;
    FILE *outKeyFile = NULL;
    X509 *caCert = NULL;
    X509 *devCert = NULL;
    EVP_PKEY *caKey = NULL;
    EVP_PKEY *devKey = NULL;
    uint8_t *weaveCert = NULL;
    uint32_t weaveCertLen;
    char *weaveCertB64 = NULL;
    uint8_t *weaveKey = NULL;
    uint32_t weaveKeyLen;
    char *weaveKeyB64 = NULL;
    bool certFileCreated = false;
    bool keyFileCreated = false;

    {
        time_t now = time(NULL);
        gValidFrom = *gmtime(&now);
        gValidFrom.tm_hour = 0;
        gValidFrom.tm_min = 0;
        gValidFrom.tm_sec = 0;
    }

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

    if (!ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets))
    {
        ExitNow(res = true);
    }

    if (gDevId == 0)
    {
        fprintf(stderr, "Please specify the device id using the --dev-id option.\n");
        ExitNow(res = false);
    }

    if (gCACertFileName == NULL)
    {
        fprintf(stderr, "Please specify the CA certificate file name using the --ca-cert option.\n");
        ExitNow(res = false);
    }

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

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

    if (gInCertKeyFileName == NULL && gOutKeyFileName == NULL)
    {
        fprintf(stderr, "Please specify the file name for the new public/private key using the --out-key option.\n");
        ExitNow(res = false);
    }

    if (gValidDays == 0)
    {
        fprintf(stderr, "Please specify the lifetime for the new CA certificate (in days) using the --lifetime option.\n");
        ExitNow(res = false);
    }

    if (gInCertKeyFileName == NULL && gCurveName == NULL)
    {
        fprintf(stderr, "Please specify an elliptic curve using the --curve option.\n");
        ExitNow(res = false);
    }

    if (gCurveName != NULL)
    {
        curveNID = OBJ_sn2nid(gCurveName);
        if (curveNID == 0)
        {
            fprintf(stderr, "Unknown elliptic curve: %s\n", gCurveName);
            ExitNow(res = false);
        }
    }

    if (gSigHashAlgo == NULL)
    {
        fprintf(stderr, "Please specify a signature hash algorithm using either the --sha1 or --sha256 options.\n");
        ExitNow(res = false);
    }

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

    if (gOutKeyFileName != NULL && access(gOutKeyFileName, R_OK) == 0)
    {
        fprintf(stderr, "weave: ERROR: Output key file already exists (%s)\n"
                        "To replace the file, please remove it and re-run the command.\n",
                        gOutKeyFileName);
        ExitNow(res = false);
    }

    outCertFile = fopen(gOutCertFileName, "w+");
    if (outCertFile == NULL)
    {
        fprintf(stderr, "weave: ERROR: Unable to create output certificate file (%s)\n"
                        "%s.\n",
                        gOutCertFileName,
                        strerror(errno));
        ExitNow(res = false);
    }
    certFileCreated = true;

    if (gOutKeyFileName != NULL)
    {
        outKeyFile = fopen(gOutKeyFileName, "w+");
        if (outKeyFile == NULL)
        {
            fprintf(stderr, "weave: ERROR: Unable to create output key file (%s)\n"
                            "%s.\n",
                            gOutKeyFileName,
                            strerror(errno));
            ExitNow(res = false);
        }
    }
    keyFileCreated = true;

    if (!InitOpenSSL())
        ExitNow(res = false);

    if (!ReadCertPEM(gCACertFileName, caCert))
        ExitNow(res = false);

    if (gInCertKeyFileName != NULL)
    {
        if (!ReadPrivateKey(gInCertKeyFileName, "Enter password for private key:", devKey))
            ExitNow(res = false);

        // If a curve name was specified on the command line, verify that it matches the curve
        // of the private key.
        if (gCurveName != NULL && EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get1_EC_KEY(devKey))) != curveNID)
        {
            fprintf(stderr, "weave: ERROR: Value given for --curve option does not match specified key (%s)\n",
                            gCurveName);
            ExitNow(res = false);
        }
    }

    if (!ReadPrivateKey(gCAKeyFileName, "Enter password for CA certificate:", caKey))
        ExitNow(res = false);

    if (!MakeDeviceCert(gDevId, caCert, caKey, gCurveName, gValidFrom, gValidDays, gSigHashAlgo, devCert, devKey))
        ExitNow(res = false);

    if (!WeaveEncodeCert(devCert, weaveCert, weaveCertLen))
        ExitNow(res = false);

    if (!EncodePrivateKey(devKey, kKeyFormat_Weave_Raw, weaveKey, weaveKeyLen))
        ExitNow(res = false);

    weaveCertB64 = Base64Encode(weaveCert, weaveCertLen);
    if (weaveCertB64 == NULL)
    {
        fprintf(stderr, "Memory allocation error\n");
        ExitNow(res = false);
    }

    weaveKeyB64 = Base64Encode(weaveKey, weaveKeyLen);
    if (weaveKeyB64 == NULL)
    {
        fprintf(stderr, "Memory allocation error\n");
        ExitNow(res = false);
    }

    if (fputs(weaveCertB64, outCertFile) == EOF)
    {
        fprintf(stderr, "weave: ERROR: Unable to write output certificate file (%s)\n"
                        "%s.\n",
                        gOutCertFileName,
                        strerror(errno));
        ExitNow(res = false);
    }

    if (outKeyFile != NULL && fputs(weaveKeyB64, outKeyFile) == EOF)
    {
        fprintf(stderr, "weave: ERROR: Unable to write output key file (%s)\n"
                        "%s.\n",
                        gOutKeyFileName,
                        strerror(errno));
        ExitNow(res = false);
    }

    res = (fclose(outCertFile) != EOF);
    outCertFile = NULL;
    if (!res)
    {
        fprintf(stderr, "weave: ERROR: Unable to write output certificate file (%s)\n"
                        "%s.\n",
                        gOutCertFileName,
                        strerror(errno));
        ExitNow();
    }

    if (outKeyFile != NULL)
    {
        res = (fclose(outKeyFile) != EOF);
        outKeyFile = NULL;
        if (!res)
        {
            fprintf(stderr, "weave: ERROR: Unable to write output key file (%s)\n"
                            "%s.\n",
                            gOutKeyFileName,
                            strerror(errno));
            ExitNow();
        }
    }

exit:
    if (weaveCertB64 != NULL)
        free(weaveCertB64);
    if (weaveKeyB64 != NULL)
        free(weaveKeyB64);
    if (caCert != NULL)
        X509_free(caCert);
    if (devCert != NULL)
        X509_free(devCert);
    if (caKey != NULL)
        EVP_PKEY_free(caKey);
    if (devKey != NULL)
        EVP_PKEY_free(devKey);
    if (weaveCert != NULL)
        free(weaveCert);
    if (weaveKey != NULL)
        free(weaveKey);
    if (outCertFile != NULL)
        fclose(outCertFile);
    if (outKeyFile != NULL)
        fclose(outKeyFile);
    if (gOutCertFileName != NULL && certFileCreated && !res)
        unlink(gOutCertFileName);
    if (gOutKeyFileName != NULL && keyFileCreated && !res)
        unlink(gOutKeyFileName);
    return res;
}

bool HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'i':
        if (!ParseEUI64(arg, gDevId))
        {
            PrintArgError("%s: Invalid value specified for device id: %s\n", progName, arg);
            return false;
        }
        break;
    case 'k':
        gInCertKeyFileName = arg;
        break;
    case 'C':
        gCACertFileName = arg;
        break;
    case 'K':
        gCAKeyFileName = arg;
        break;
    case 'o':
        gOutCertFileName = arg;
        break;
    case 'O':
        gOutKeyFileName = arg;
        break;
    case 'u':
        gCurveName = arg;
        break;
    case 'V':
        if (!ParseDateTime(arg, gValidFrom))
        {
            PrintArgError("%s: Invalid value specified for certificate validity date: %s\n", progName, arg);
            return false;
        }
        break;
    case 'l':
        if (!ParseInt(arg, gValidDays) || gValidDays < 0)
        {
            PrintArgError("%s: Invalid value specified for certificate lifetime: %s\n", progName, arg);
            return false;
        }
        break;
    case '1':
        gSigHashAlgo = EVP_sha1();
        break;
    case '2':
        gSigHashAlgo = EVP_sha256();
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}
