/*
 * Copyright (c) 2018 Fastly, Kazuho Oku
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include <assert.h>
#include <getopt.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/pem.h>
#include "picotls.h"
#include "picotls/pembase64.h"
#include "picotls/openssl.h"

static int emit_esni(ptls_key_exchange_context_t **key_exchanges, ptls_cipher_suite_t **cipher_suites, uint16_t padded_length,
                     uint64_t not_before, uint64_t lifetime)
{
    ptls_buffer_t buf;
    ptls_key_exchange_context_t *ctx[256] = {NULL};
    int ret;

    ptls_buffer_init(&buf, "", 0);

    ptls_buffer_push16(&buf, PTLS_ESNI_VERSION_DRAFT02);
    ptls_buffer_push(&buf, 0, 0, 0, 0); /* checksum, filled later */
    ptls_buffer_push_block(&buf, 2, {
        size_t i;
        for (i = 0; key_exchanges[i] != NULL; ++i) {
            ptls_buffer_push16(&buf, key_exchanges[i]->algo->id);
            ptls_buffer_push_block(&buf, 2,
                                   { ptls_buffer_pushv(&buf, key_exchanges[i]->pubkey.base, key_exchanges[i]->pubkey.len); });
        }
    });
    ptls_buffer_push_block(&buf, 2, {
        size_t i;
        for (i = 0; cipher_suites[i] != NULL; ++i)
            ptls_buffer_push16(&buf, cipher_suites[i]->id);
    });
    ptls_buffer_push16(&buf, padded_length);
    ptls_buffer_push64(&buf, not_before);
    ptls_buffer_push64(&buf, not_before + lifetime - 1);
    ptls_buffer_push_block(&buf, 2, {});
    { /* fill checksum */
        uint8_t d[PTLS_SHA256_DIGEST_SIZE];
        ptls_calc_hash(&ptls_openssl_sha256, d, buf.base, buf.off);
        memcpy(buf.base + 2, d, 4);
    }

    /* emit the structure to stdout */
    fwrite(buf.base, 1, buf.off, stdout);
    fflush(stdout);

    ret = 0;
Exit : {
    size_t i;
    for (i = 0; ctx[i] != NULL; ++i)
        ctx[i]->on_exchange(ctx + i, 1, NULL, ptls_iovec_init(NULL, 0));
}
    ptls_buffer_dispose(&buf);
    return ret;
}

static void usage(const char *cmd, int status)
{
    printf("picotls-esni - generates an ESNI Resource Record\n"
           "\n"
           "Usage: %s [options]\n"
           "Options:\n"
           "  -K <key-file>       private key files (repeat the option to include multiple\n"
           "                      keys)\n"
           "  -c <cipher-suite>   aes128-gcm, chacha20-poly1305, ...\n"
           "  -d <days>           number of days until expiration (default: 90)\n"
           "  -p <padded-length>  padded length (default: 260)\n"
           "  -h                  prints this help\n"
           "\n"
           "-c and -x can be used multiple times.\n"
           "\n",
           cmd);
    exit(status);
}

int main(int argc, char **argv)
{
    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();
#if !defined(OPENSSL_NO_ENGINE)
    /* Load all compiled-in ENGINEs */
    ENGINE_load_builtin_engines();
    ENGINE_register_all_ciphers();
    ENGINE_register_all_digests();
#endif

    struct {
        ptls_key_exchange_context_t *elements[256];
        size_t count;
    } key_exchanges = {{NULL}, 0};
    struct {
        ptls_cipher_suite_t *elements[256];
        size_t count;
    } cipher_suites = {{NULL}, 0};
    uint16_t padded_length = 260;
    uint64_t lifetime = 90 * 86400;

    int ch;
    while ((ch = getopt(argc, argv, "K:c:d:p:h")) != -1) {
        switch (ch) {
        case 'K': {
            FILE *fp;
            EVP_PKEY *pkey;
            if ((fp = fopen(optarg, "rt")) == NULL) {
                fprintf(stderr, "failed to open file:%s:%s\n", optarg, strerror(errno));
                exit(1);
            }
            if ((pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
                fprintf(stderr, "failed to read private key from file:%s:%s\n", optarg, strerror(errno));
                exit(1);
            }
            fclose(fp);
            if (ptls_openssl_create_key_exchange(key_exchanges.elements + key_exchanges.count++, pkey) != 0) {
                fprintf(stderr, "unknown type of private key found in file:%s\n", optarg);
                exit(1);
            }
            EVP_PKEY_free(pkey);
        } break;
        case 'c': {
            size_t i;
            for (i = 0; ptls_openssl_cipher_suites[i] != NULL; ++i)
                if (strcasecmp(ptls_openssl_cipher_suites[i]->aead->name, optarg) == 0)
                    break;
            if (ptls_openssl_cipher_suites[i] == NULL) {
                fprintf(stderr, "unknown cipher-suite: %s\n", optarg);
                exit(1);
            }
            cipher_suites.elements[cipher_suites.count++] = ptls_openssl_cipher_suites[i];
        } break;
        case 'd':
            if (sscanf(optarg, "%" SCNu64, &lifetime) != 1 || lifetime == 0) {
                fprintf(stderr, "lifetime must be a positive integer\n");
                exit(1);
            }
            lifetime *= 86400; /* convert to seconds */
            break;
        case 'p':
            if (sscanf(optarg, "%" SCNu16, &padded_length) != 1 || padded_length == 0) {
                fprintf(stderr, "padded length must be a positive integer\n");
                exit(1);
            }
            break;
        case 'h':
            usage(argv[0], 0);
            break;
        default:
            usage(argv[0], 1);
            break;
        }
    }
    if (cipher_suites.count == 0)
        cipher_suites.elements[cipher_suites.count++] = &ptls_openssl_aes128gcmsha256;
    if (key_exchanges.count == 0) {
        fprintf(stderr, "no private key specified\n");
        exit(1);
    }

    argc -= optind;
    argv += optind;

    if (emit_esni(key_exchanges.elements, cipher_suites.elements, padded_length, time(NULL), lifetime) != 0) {
        fprintf(stderr, "failed to generate ESNI private structure.\n");
        exit(1);
    }

    return 0;
}
