/*
 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/opensslconf.h>

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/core_names.h>
#include <openssl/core_dispatch.h>
#include <openssl/param_build.h>
#include <openssl/encoder.h>
#include <openssl/decoder.h>

#define DEFBITS 2048

static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh);
static int gendh_cb(EVP_PKEY_CTX *ctx);

typedef enum OPTION_choice {
    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
    OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
    OPT_DSAPARAM, OPT_2, OPT_3, OPT_5,
    OPT_R_ENUM, OPT_PROV_ENUM
} OPTION_CHOICE;

const OPTIONS dhparam_options[] = {
    {OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits]\n"},

    OPT_SECTION("General"),
    {"help", OPT_HELP, '-', "Display this summary"},
    {"check", OPT_CHECK, '-', "Check the DH parameters"},
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_DEPRECATED_3_0)
    {"dsaparam", OPT_DSAPARAM, '-',
     "Read or generate DSA parameters, convert to DH"},
#endif
#ifndef OPENSSL_NO_ENGINE
    {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
#endif

    OPT_SECTION("Input"),
    {"in", OPT_IN, '<', "Input file"},
    {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"},

    OPT_SECTION("Output"),
    {"out", OPT_OUT, '>', "Output file"},
    {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"},
    {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"},
    {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"},
    {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
    {"3", OPT_3, '-', "Generate parameters using 3 as the generator value"},
    {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},

    OPT_R_OPTIONS,
    OPT_PROV_OPTIONS,

    OPT_PARAMETERS(),
    {"numbits", 0, 0, "Number of bits if generating parameters (optional)"},
    {NULL}
};

int dhparam_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    EVP_PKEY *pkey = NULL, *tmppkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    char *infile = NULL, *outfile = NULL, *prog;
    ENGINE *e = NULL;
    int dsaparam = 0;
    int text = 0, ret = 1, num = 0, g = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, dhparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(dhparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_DSAPARAM:
            dsaparam = 1;
            break;
        case OPT_2:
            g = 2;
            break;
        case OPT_3:
            g = 3;
            break;
        case OPT_5:
            g = 5;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_R_CASES:
            if (!opt_rand(o))
                goto end;
            break;
        case OPT_PROV_CASES:
            if (!opt_provider(o))
                goto end;
            break;
        }
    }

    /* One optional argument, bitsize to generate. */
    argc = opt_num_rest();
    argv = opt_rest();
    if (argc == 1) {
        if (!opt_int(argv[0], &num) || num <= 0)
            goto opthelp;
    } else if (argc != 0) {
        goto opthelp;
    }
    if (!app_RAND_load())
        goto end;

    if (g && !num)
        num = DEFBITS;

    if (dsaparam && g) {
        BIO_printf(bio_err,
                   "Error, generator may not be chosen for DSA parameters\n");
        goto end;
    }

    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    /* DH parameters */
    if (num && !g)
        g = 2;

    if (num) {
        const char *alg = dsaparam ? "DSA" : "DH";

        ctx = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL);
        if (ctx == NULL) {
            BIO_printf(bio_err,
                        "Error, %s param generation context allocation failed\n",
                        alg);
            goto end;
        }
        EVP_PKEY_CTX_set_cb(ctx, gendh_cb);
        EVP_PKEY_CTX_set_app_data(ctx, bio_err);
        BIO_printf(bio_err,
                    "Generating %s parameters, %d bit long %sprime\n",
                    alg, num, dsaparam ? "" : "safe ");

        if (!EVP_PKEY_paramgen_init(ctx)) {
            BIO_printf(bio_err,
                        "Error, unable to initialise %s parameters\n",
                        alg);
            goto end;
        }

        if (dsaparam) {
            if (!EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, num)) {
                BIO_printf(bio_err, "Error, unable to set DSA prime length\n");
                goto end;
            }
        } else {
            if (!EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, num)) {
                BIO_printf(bio_err, "Error, unable to set DH prime length\n");
                goto end;
            }
            if (!EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, g)) {
                BIO_printf(bio_err, "Error, unable to set generator\n");
                goto end;
            }
        }

        if (!EVP_PKEY_paramgen(ctx, &tmppkey)) {
            BIO_printf(bio_err, "Error, %s generation failed\n", alg);
            goto end;
        }

        EVP_PKEY_CTX_free(ctx);
        ctx = NULL;
        if (dsaparam) {
            pkey = dsa_to_dh(tmppkey);
            if (pkey == NULL)
                goto end;
            EVP_PKEY_free(tmppkey);
        } else {
            pkey = tmppkey;
        }
        tmppkey = NULL;
    } else {
        OSSL_DECODER_CTX *decoderctx = NULL;
        const char *keytype = "DH";
        int done;

        in = bio_open_default(infile, 'r', informat);
        if (in == NULL)
            goto end;

        do {
            /*
             * We assume we're done unless we explicitly want to retry and set
             * this to 0 below.
             */
            done = 1;
            /*
            * We set NULL for the keytype to allow any key type. We don't know
            * if we're going to get DH or DHX (or DSA in the event of dsaparam).
            * We check that we got one of those key types afterwards.
            */
            decoderctx
                = OSSL_DECODER_CTX_new_for_pkey(&tmppkey,
                                                (informat == FORMAT_ASN1)
                                                    ? "DER" : "PEM",
                                                NULL,
                                                (informat == FORMAT_ASN1)
                                                    ? keytype : NULL,
                                                OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
                                                NULL, NULL);

            if (decoderctx != NULL
                    && !OSSL_DECODER_from_bio(decoderctx, in)
                    && informat == FORMAT_ASN1
                    && strcmp(keytype, "DH") == 0) {
                /*
                * When reading DER we explicitly state the expected keytype
                * because, unlike PEM, there is no header to declare what
                * the contents of the DER file are. The decoders just try
                * and guess. Unfortunately with DHX key types they may guess
                * wrong and think we have a DSA keytype. Therefore we try
                * both DH and DHX sequentially.
                */
                keytype = "DHX";
                /*
                    * BIO_reset() returns 0 for success for file BIOs only!!!
                    * This won't work for stdin (and never has done)
                    * TODO: We should fix this at some point
                    */
                if (BIO_reset(in) == 0)
                    done = 0;
            }
            OSSL_DECODER_CTX_free(decoderctx);
        } while (!done);
        if (tmppkey == NULL) {
            BIO_printf(bio_err, "Error, unable to load parameters\n");
            goto end;
        }

        if (dsaparam) {
            if (!EVP_PKEY_is_a(tmppkey, "DSA")) {
                BIO_printf(bio_err, "Error, unable to load DSA parameters\n");
                goto end;
            }
            pkey = dsa_to_dh(tmppkey);
            if (pkey == NULL)
                goto end;
        } else {
            if (!EVP_PKEY_is_a(tmppkey, "DH")
                    && !EVP_PKEY_is_a(tmppkey, "DHX")) {
                BIO_printf(bio_err, "Error, unable to load DH parameters\n");
                goto end;
            }
            pkey = tmppkey;
            tmppkey = NULL;
        }
    }

    if (text)
        EVP_PKEY_print_params(out, pkey, 4, NULL);

    if (check) {
        ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
        if (ctx == NULL) {
            BIO_printf(bio_err, "Error, failed to check DH parameters\n");
            goto end;
        }
        if (!EVP_PKEY_param_check(ctx)) {
            BIO_printf(bio_err, "Error, invalid parameters generated\n");
            goto end;
        }
        BIO_printf(bio_err, "DH parameters appear to be ok.\n");
    }

    if (!noout) {
        OSSL_ENCODER_CTX *ectx =
            OSSL_ENCODER_CTX_new_for_pkey(pkey,
                                          OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
                                          outformat == FORMAT_ASN1
                                              ? "DER" : "PEM",
                                          NULL, NULL);

        if (ectx == NULL || !OSSL_ENCODER_to_bio(ectx, out)) {
            OSSL_ENCODER_CTX_free(ectx);
            BIO_printf(bio_err, "Error, unable to write DH parameters\n");
            goto end;
        }
        OSSL_ENCODER_CTX_free(ectx);
    }
    ret = 0;
 end:
    if (ret != 0)
        ERR_print_errors(bio_err);
    BIO_free(in);
    BIO_free_all(out);
    EVP_PKEY_free(pkey);
    EVP_PKEY_free(tmppkey);
    EVP_PKEY_CTX_free(ctx);
    release_engine(e);
    return ret;
}

/*
 * Historically we had the low level call DSA_dup_DH() to do this.
 * That is now deprecated with no replacement. Since we still need to do this
 * for backwards compatibility reasons, we do it "manually".
 */
static EVP_PKEY *dsa_to_dh(EVP_PKEY *dh)
{
    OSSL_PARAM_BLD *tmpl = NULL;
    OSSL_PARAM *params = NULL;
    BIGNUM *bn_p = NULL, *bn_q = NULL, *bn_g = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey = NULL;

    if (!EVP_PKEY_get_bn_param(dh, OSSL_PKEY_PARAM_FFC_P, &bn_p)
            || !EVP_PKEY_get_bn_param(dh, OSSL_PKEY_PARAM_FFC_Q, &bn_q)
            || !EVP_PKEY_get_bn_param(dh, OSSL_PKEY_PARAM_FFC_G, &bn_g)) {
        BIO_printf(bio_err, "Error, failed to set DH parameters\n");
        goto err;
    }

    if ((tmpl = OSSL_PARAM_BLD_new()) == NULL
            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P,
                                        bn_p)
            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q,
                                        bn_q)
            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G,
                                        bn_g)
            || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
        BIO_printf(bio_err, "Error, failed to set DH parameters\n");
        goto err;
    }

    ctx = EVP_PKEY_CTX_new_from_name(NULL, "DHX", NULL);
    if (ctx == NULL
            || !EVP_PKEY_fromdata_init(ctx)
            || !EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEY_PARAMETERS, params)) {
        BIO_printf(bio_err, "Error, failed to set DH parameters\n");
        goto err;
    }

 err:
    EVP_PKEY_CTX_free(ctx);
    OSSL_PARAM_free(params);
    OSSL_PARAM_BLD_free(tmpl);
    BN_free(bn_p);
    BN_free(bn_q);
    BN_free(bn_g);
    return pkey;
}

static int gendh_cb(EVP_PKEY_CTX *ctx)
{
    int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
    static const char symbols[] = ".+*\n";
    char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?';

    BIO_write(b, &c, 1);
    (void)BIO_flush(b);
    return 1;
}
