/*
 * Copyright 1995-2023 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_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

    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;
    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_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_puts(bio_err,
            "Error, generator may not be chosen for DSA parameters\n");
        goto end;
    }

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

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

        if (infile != NULL) {
            BIO_printf(bio_err, "Warning, input file %s ignored\n", infile);
        }

        ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), alg, app_get0_propq());
        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) <= 0) {
                BIO_puts(bio_err, "Error, unable to set DSA prime length\n");
                goto end;
            }
        } else {
            if (EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, num) <= 0) {
                BIO_puts(bio_err, "Error, unable to set DH prime length\n");
                goto end;
            }
            if (EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, g) <= 0) {
                BIO_puts(bio_err, "Error, unable to set generator\n");
                goto end;
            }
        }

        tmppkey = app_paramgen(ctx, alg);
        if (tmppkey == NULL)
            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)
                 */
                if (BIO_reset(in) == 0)
                    done = 0;
            }
            OSSL_DECODER_CTX_free(decoderctx);
        } while (!done);
        if (tmppkey == NULL) {
            BIO_puts(bio_err, "Error, unable to load parameters\n");
            goto end;
        }

        if (dsaparam) {
            if (!EVP_PKEY_is_a(tmppkey, "DSA")) {
                BIO_puts(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_puts(bio_err, "Error, unable to load DH parameters\n");
                goto end;
            }
            pkey = tmppkey;
            tmppkey = NULL;
        }
    }

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

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

    if (check) {
        ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), pkey, app_get0_propq());
        if (ctx == NULL) {
            BIO_puts(bio_err, "Error, failed to check DH parameters\n");
            goto end;
        }
        if (EVP_PKEY_param_check(ctx) <= 0) {
            BIO_puts(bio_err, "Error, invalid parameters generated\n");
            goto end;
        }
        BIO_puts(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_puts(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);
    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_puts(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_puts(bio_err, "Error, failed to set DH parameters\n");
        goto err;
    }

    ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "DHX", app_get0_propq());
    if (ctx == NULL
        || EVP_PKEY_fromdata_init(ctx) <= 0
        || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEY_PARAMETERS, params) <= 0) {
        BIO_puts(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;
}
