/*
 * 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 verbose = 1;

typedef enum OPTION_choice {
    OPT_COMMON,
    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_VERBOSE, OPT_QUIET,
    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"},
    {"verbose", OPT_VERBOSE, '-', "Verbose output"},
    {"quiet", OPT_QUIET, '-', "Terse output"},

    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_VERBOSE:
            verbose = 1;
            break;
        case OPT_QUIET:
            verbose = 0;
            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 (!opt_check_rest_arg(NULL)) {
        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_app_data(ctx, bio_err);
        if (verbose) {
            EVP_PKEY_CTX_set_cb(ctx, progress_cb);
            BIO_printf(bio_err,
                        "Generating %s parameters, %d bit long %sprime\n",
                        alg, num, dsaparam ? "" : "safe ");
        }

        if (EVP_PKEY_paramgen_init(ctx) <= 0) {
            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;
            }
        }

        tmppkey = app_paramgen(ctx, alg);
        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)
                 */
                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) <= 0
            || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEY_PARAMETERS, params) <= 0) {
        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;
}

