/*
 * Copyright 2006-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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "apps.h"
#include "progs.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>

typedef enum OPTION_choice {
    OPT_COMMON,
    OPT_IN,
    OPT_OUT,
    OPT_TEXT,
    OPT_NOOUT,
    OPT_CHECK,
    OPT_PROV_ENUM
} OPTION_CHOICE;

const OPTIONS pkeyparam_options[] = {
    OPT_SECTION("General"),
    { "help", OPT_HELP, '-', "Display this summary" },
    { "check", OPT_CHECK, '-', "Check key param consistency" },

    OPT_SECTION("Input"),
    { "in", OPT_IN, '<', "Input file" },

    OPT_SECTION("Output"),
    { "out", OPT_OUT, '>', "Output file" },
    { "text", OPT_TEXT, '-', "Print parameters as text" },
    { "noout", OPT_NOOUT, '-', "Don't output encoded parameters" },

    OPT_PROV_OPTIONS,
    { NULL }
};

int pkeyparam_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    EVP_PKEY *pkey = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    int text = 0, noout = 0, ret = EXIT_FAILURE, check = 0, r;
    OPTION_CHOICE o;
    char *infile = NULL, *outfile = NULL, *prog;

    prog = opt_init(argc, argv, pkeyparam_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(pkeyparam_options);
            ret = 0;
            goto end;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_PROV_CASES:
            if (!opt_provider(o))
                goto end;
            break;
        }
    }

    /* No extra arguments. */
    if (!opt_check_rest_arg(NULL))
        goto opthelp;

    in = bio_open_default(infile, 'r', FORMAT_PEM);
    if (in == NULL)
        goto end;
    pkey = PEM_read_bio_Parameters_ex(in, NULL, app_get0_libctx(),
        app_get0_propq());
    if (pkey == NULL) {
        BIO_puts(bio_err, "Error reading parameters\n");
        ERR_print_errors(bio_err);
        goto end;
    }
    out = bio_open_default(outfile, 'w', FORMAT_PEM);
    if (out == NULL)
        goto end;

    if (check) {
        ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), pkey,
            app_get0_propq());
        if (ctx == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }

        r = EVP_PKEY_param_check(ctx);

        if (r == 1) {
            BIO_puts(out, "Parameters are valid\n");
        } else {
            /*
             * Note: at least for RSA keys if this function returns
             * -1, there will be no error reasons.
             */
            BIO_puts(bio_err, "Parameters are invalid\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (!noout)
        PEM_write_bio_Parameters(out, pkey);

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

    ret = EXIT_SUCCESS;

end:
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey);
    BIO_free_all(out);
    BIO_free(in);

    return ret;
}
