1635165faSspz /*
2*b0d17251Schristos * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
3c7da899bSchristos *
4*b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
5c7da899bSchristos * this file except in compliance with the License. You can obtain a copy
6c7da899bSchristos * in the file LICENSE in the source distribution or at
7c7da899bSchristos * https://www.openssl.org/source/license.html
8a89c9211Schristos */
9c7da899bSchristos
10a89c9211Schristos #include <stdio.h>
11a89c9211Schristos #include <string.h>
12*b0d17251Schristos #include <stdlib.h>
13a89c9211Schristos #include "apps.h"
1413d40330Schristos #include "progs.h"
15a89c9211Schristos #include <openssl/pem.h>
16a89c9211Schristos #include <openssl/err.h>
17a89c9211Schristos #include <openssl/evp.h>
18a89c9211Schristos
19c7da899bSchristos typedef enum OPTION_choice {
20*b0d17251Schristos OPT_COMMON,
2113d40330Schristos OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT,
22*b0d17251Schristos OPT_ENGINE, OPT_CHECK,
23*b0d17251Schristos OPT_PROV_ENUM
24c7da899bSchristos } OPTION_CHOICE;
25a89c9211Schristos
2613d40330Schristos const OPTIONS pkeyparam_options[] = {
27*b0d17251Schristos OPT_SECTION("General"),
28c7da899bSchristos {"help", OPT_HELP, '-', "Display this summary"},
29c7da899bSchristos #ifndef OPENSSL_NO_ENGINE
30c7da899bSchristos {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
31c7da899bSchristos #endif
3213d40330Schristos {"check", OPT_CHECK, '-', "Check key param consistency"},
33*b0d17251Schristos
34*b0d17251Schristos OPT_SECTION("Input"),
35*b0d17251Schristos {"in", OPT_IN, '<', "Input file"},
36*b0d17251Schristos
37*b0d17251Schristos OPT_SECTION("Output"),
38*b0d17251Schristos {"out", OPT_OUT, '>', "Output file"},
39*b0d17251Schristos {"text", OPT_TEXT, '-', "Print parameters as text"},
40*b0d17251Schristos {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"},
41*b0d17251Schristos
42*b0d17251Schristos OPT_PROV_OPTIONS,
43c7da899bSchristos {NULL}
44c7da899bSchristos };
45a89c9211Schristos
pkeyparam_main(int argc,char ** argv)46c7da899bSchristos int pkeyparam_main(int argc, char **argv)
47a89c9211Schristos {
4834505c60Sspz ENGINE *e = NULL;
49c7da899bSchristos BIO *in = NULL, *out = NULL;
50c7da899bSchristos EVP_PKEY *pkey = NULL;
51*b0d17251Schristos EVP_PKEY_CTX *ctx = NULL;
52*b0d17251Schristos int text = 0, noout = 0, ret = EXIT_FAILURE, check = 0, r;
53c7da899bSchristos OPTION_CHOICE o;
54c7da899bSchristos char *infile = NULL, *outfile = NULL, *prog;
55a89c9211Schristos
56c7da899bSchristos prog = opt_init(argc, argv, pkeyparam_options);
57c7da899bSchristos while ((o = opt_next()) != OPT_EOF) {
58c7da899bSchristos switch (o) {
59c7da899bSchristos case OPT_EOF:
60c7da899bSchristos case OPT_ERR:
61c7da899bSchristos opthelp:
62c7da899bSchristos BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
63a89c9211Schristos goto end;
64c7da899bSchristos case OPT_HELP:
65c7da899bSchristos opt_help(pkeyparam_options);
66c7da899bSchristos ret = 0;
67c7da899bSchristos goto end;
68c7da899bSchristos case OPT_IN:
69c7da899bSchristos infile = opt_arg();
70c7da899bSchristos break;
71c7da899bSchristos case OPT_OUT:
72c7da899bSchristos outfile = opt_arg();
73c7da899bSchristos break;
74c7da899bSchristos case OPT_ENGINE:
75c7da899bSchristos e = setup_engine(opt_arg(), 0);
76c7da899bSchristos break;
77c7da899bSchristos case OPT_TEXT:
78a89c9211Schristos text = 1;
79c7da899bSchristos break;
80c7da899bSchristos case OPT_NOOUT:
81a89c9211Schristos noout = 1;
82c7da899bSchristos break;
8313d40330Schristos case OPT_CHECK:
8413d40330Schristos check = 1;
8513d40330Schristos break;
86*b0d17251Schristos case OPT_PROV_CASES:
87*b0d17251Schristos if (!opt_provider(o))
88*b0d17251Schristos goto end;
89*b0d17251Schristos break;
90a89c9211Schristos }
91a89c9211Schristos }
92*b0d17251Schristos
93*b0d17251Schristos /* No extra arguments. */
94c7da899bSchristos argc = opt_num_rest();
95c7da899bSchristos if (argc != 0)
96c7da899bSchristos goto opthelp;
97a89c9211Schristos
98c7da899bSchristos in = bio_open_default(infile, 'r', FORMAT_PEM);
99c7da899bSchristos if (in == NULL)
100a89c9211Schristos goto end;
101c7da899bSchristos out = bio_open_default(outfile, 'w', FORMAT_PEM);
102c7da899bSchristos if (out == NULL)
103a89c9211Schristos goto end;
104*b0d17251Schristos pkey = PEM_read_bio_Parameters_ex(in, NULL, app_get0_libctx(),
105*b0d17251Schristos app_get0_propq());
10613d40330Schristos if (pkey == NULL) {
107a89c9211Schristos BIO_printf(bio_err, "Error reading parameters\n");
108a89c9211Schristos ERR_print_errors(bio_err);
109a89c9211Schristos goto end;
110a89c9211Schristos }
111a89c9211Schristos
11213d40330Schristos if (check) {
113*b0d17251Schristos if (e == NULL)
114*b0d17251Schristos ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), pkey,
115*b0d17251Schristos app_get0_propq());
116*b0d17251Schristos else
11713d40330Schristos ctx = EVP_PKEY_CTX_new(pkey, e);
11813d40330Schristos if (ctx == NULL) {
11913d40330Schristos ERR_print_errors(bio_err);
12013d40330Schristos goto end;
12113d40330Schristos }
12213d40330Schristos
12313d40330Schristos r = EVP_PKEY_param_check(ctx);
12413d40330Schristos
12513d40330Schristos if (r == 1) {
12613d40330Schristos BIO_printf(out, "Parameters are valid\n");
12713d40330Schristos } else {
12813d40330Schristos /*
12913d40330Schristos * Note: at least for RSA keys if this function returns
13013d40330Schristos * -1, there will be no error reasons.
13113d40330Schristos */
132*b0d17251Schristos BIO_printf(bio_err, "Parameters are invalid\n");
133*b0d17251Schristos ERR_print_errors(bio_err);
134*b0d17251Schristos goto end;
13513d40330Schristos }
13613d40330Schristos }
13713d40330Schristos
138a89c9211Schristos if (!noout)
139a89c9211Schristos PEM_write_bio_Parameters(out, pkey);
140a89c9211Schristos
141a89c9211Schristos if (text)
142a89c9211Schristos EVP_PKEY_print_params(out, pkey, 0, NULL);
143a89c9211Schristos
144*b0d17251Schristos ret = EXIT_SUCCESS;
145a89c9211Schristos
146a89c9211Schristos end:
147*b0d17251Schristos EVP_PKEY_CTX_free(ctx);
148a89c9211Schristos EVP_PKEY_free(pkey);
14934505c60Sspz release_engine(e);
150a89c9211Schristos BIO_free_all(out);
151a89c9211Schristos BIO_free(in);
152a89c9211Schristos
153a89c9211Schristos return ret;
154a89c9211Schristos }
155