Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/apps/dsaparam.c
105585 views
1
/*
2
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
3
*
4
* Licensed under the Apache License 2.0 (the "License"). You may not use
5
* this file except in compliance with the License. You can obtain a copy
6
* in the file LICENSE in the source distribution or at
7
* https://www.openssl.org/source/license.html
8
*/
9
10
#include <openssl/opensslconf.h>
11
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <time.h>
15
#include <string.h>
16
#include "apps.h"
17
#include "progs.h"
18
#include <openssl/bio.h>
19
#include <openssl/err.h>
20
#include <openssl/bn.h>
21
#include <openssl/dsa.h>
22
#include <openssl/x509.h>
23
#include <openssl/pem.h>
24
25
static int verbose = 0;
26
27
typedef enum OPTION_choice {
28
OPT_COMMON,
29
OPT_INFORM,
30
OPT_OUTFORM,
31
OPT_IN,
32
OPT_OUT,
33
OPT_TEXT,
34
OPT_NOOUT,
35
OPT_GENKEY,
36
OPT_ENGINE,
37
OPT_VERBOSE,
38
OPT_QUIET,
39
OPT_R_ENUM,
40
OPT_PROV_ENUM
41
} OPTION_CHOICE;
42
43
const OPTIONS dsaparam_options[] = {
44
{ OPT_HELP_STR, 1, '-', "Usage: %s [options] [numbits] [numqbits]\n" },
45
46
OPT_SECTION("General"),
47
{ "help", OPT_HELP, '-', "Display this summary" },
48
#ifndef OPENSSL_NO_ENGINE
49
{ "engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device" },
50
#endif
51
52
OPT_SECTION("Input"),
53
{ "in", OPT_IN, '<', "Input file" },
54
{ "inform", OPT_INFORM, 'F', "Input format - DER or PEM" },
55
56
OPT_SECTION("Output"),
57
{ "out", OPT_OUT, '>', "Output file" },
58
{ "outform", OPT_OUTFORM, 'F', "Output format - DER or PEM" },
59
{ "text", OPT_TEXT, '-', "Print as text" },
60
{ "noout", OPT_NOOUT, '-', "No output" },
61
{ "verbose", OPT_VERBOSE, '-', "Verbose output" },
62
{ "quiet", OPT_QUIET, '-', "Terse output" },
63
{ "genkey", OPT_GENKEY, '-', "Generate a DSA key" },
64
65
OPT_R_OPTIONS,
66
OPT_PROV_OPTIONS,
67
68
OPT_PARAMETERS(),
69
{ "numbits", 0, 0, "Number of bits if generating parameters or key (optional)" },
70
{ "numqbits", 0, 0, "Number of bits in the subprime parameter q if generating parameters or key (optional)" },
71
{ NULL }
72
};
73
74
int dsaparam_main(int argc, char **argv)
75
{
76
ENGINE *e = NULL;
77
BIO *out = NULL;
78
EVP_PKEY *params = NULL, *pkey = NULL;
79
EVP_PKEY_CTX *ctx = NULL;
80
int numbits = -1, numqbits = -1, num = 0, genkey = 0;
81
int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, noout = 0;
82
int ret = 1, i, text = 0, private = 0;
83
char *infile = NULL, *outfile = NULL, *prog;
84
OPTION_CHOICE o;
85
86
prog = opt_init(argc, argv, dsaparam_options);
87
while ((o = opt_next()) != OPT_EOF) {
88
switch (o) {
89
case OPT_EOF:
90
case OPT_ERR:
91
opthelp:
92
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
93
goto end;
94
case OPT_HELP:
95
opt_help(dsaparam_options);
96
ret = 0;
97
goto end;
98
case OPT_INFORM:
99
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
100
goto opthelp;
101
break;
102
case OPT_IN:
103
infile = opt_arg();
104
break;
105
case OPT_OUTFORM:
106
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
107
goto opthelp;
108
break;
109
case OPT_OUT:
110
outfile = opt_arg();
111
break;
112
case OPT_ENGINE:
113
e = setup_engine(opt_arg(), 0);
114
break;
115
case OPT_TEXT:
116
text = 1;
117
break;
118
case OPT_GENKEY:
119
genkey = 1;
120
break;
121
case OPT_R_CASES:
122
if (!opt_rand(o))
123
goto end;
124
break;
125
case OPT_PROV_CASES:
126
if (!opt_provider(o))
127
goto end;
128
break;
129
case OPT_NOOUT:
130
noout = 1;
131
break;
132
case OPT_VERBOSE:
133
verbose = 1;
134
break;
135
case OPT_QUIET:
136
verbose = 0;
137
break;
138
}
139
}
140
141
/* Optional args are bitsize and q bitsize. */
142
argc = opt_num_rest();
143
argv = opt_rest();
144
if (argc == 2) {
145
if (!opt_int(argv[0], &num) || num < 0)
146
goto opthelp;
147
if (!opt_int(argv[1], &numqbits) || numqbits < 0)
148
goto opthelp;
149
} else if (argc == 1) {
150
if (!opt_int(argv[0], &num) || num < 0)
151
goto opthelp;
152
} else if (!opt_check_rest_arg(NULL)) {
153
goto opthelp;
154
}
155
if (!app_RAND_load())
156
goto end;
157
158
/* generate a key */
159
numbits = num;
160
private = genkey ? 1 : 0;
161
162
ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "DSA", app_get0_propq());
163
if (ctx == NULL) {
164
BIO_printf(bio_err,
165
"Error, DSA parameter generation context allocation failed\n");
166
goto end;
167
}
168
if (numbits > 0) {
169
if (numbits > OPENSSL_DSA_MAX_MODULUS_BITS)
170
BIO_printf(bio_err,
171
"Warning: It is not recommended to use more than %d bit for DSA keys.\n"
172
" Your key size is %d! Larger key size may behave not as expected.\n",
173
OPENSSL_DSA_MAX_MODULUS_BITS, numbits);
174
175
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
176
if (verbose) {
177
EVP_PKEY_CTX_set_cb(ctx, progress_cb);
178
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
179
num);
180
BIO_printf(bio_err, "This could take some time\n");
181
}
182
if (EVP_PKEY_paramgen_init(ctx) <= 0) {
183
BIO_printf(bio_err,
184
"Error, DSA key generation paramgen init failed\n");
185
goto end;
186
}
187
if (EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, num) <= 0) {
188
BIO_printf(bio_err,
189
"Error, DSA key generation setting bit length failed\n");
190
goto end;
191
}
192
if (numqbits > 0) {
193
if (EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, numqbits) <= 0) {
194
BIO_printf(bio_err,
195
"Error, DSA key generation setting subprime bit length failed\n");
196
goto end;
197
}
198
}
199
params = app_paramgen(ctx, "DSA");
200
} else {
201
params = load_keyparams(infile, informat, 1, "DSA", "DSA parameters");
202
}
203
if (params == NULL) {
204
/* Error message should already have been displayed */
205
goto end;
206
}
207
208
out = bio_open_owner(outfile, outformat, private);
209
if (out == NULL)
210
goto end;
211
212
if (text) {
213
EVP_PKEY_print_params(out, params, 0, NULL);
214
}
215
216
if (outformat == FORMAT_ASN1 && genkey)
217
noout = 1;
218
219
if (!noout) {
220
if (outformat == FORMAT_ASN1)
221
i = i2d_KeyParams_bio(out, params);
222
else
223
i = PEM_write_bio_Parameters(out, params);
224
if (!i) {
225
BIO_printf(bio_err, "Error, unable to write DSA parameters\n");
226
goto end;
227
}
228
}
229
if (genkey) {
230
EVP_PKEY_CTX_free(ctx);
231
ctx = EVP_PKEY_CTX_new_from_pkey(app_get0_libctx(), params,
232
app_get0_propq());
233
if (ctx == NULL) {
234
BIO_printf(bio_err,
235
"Error, DSA key generation context allocation failed\n");
236
goto end;
237
}
238
if (EVP_PKEY_keygen_init(ctx) <= 0) {
239
BIO_printf(bio_err,
240
"Error, unable to initialise for key generation\n");
241
goto end;
242
}
243
pkey = app_keygen(ctx, "DSA", numbits, verbose);
244
if (pkey == NULL)
245
goto end;
246
assert(private);
247
if (outformat == FORMAT_ASN1)
248
i = i2d_PrivateKey_bio(out, pkey);
249
else
250
i = PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL);
251
}
252
ret = 0;
253
end:
254
if (ret != 0)
255
ERR_print_errors(bio_err);
256
BIO_free_all(out);
257
EVP_PKEY_CTX_free(ctx);
258
EVP_PKEY_free(pkey);
259
EVP_PKEY_free(params);
260
release_engine(e);
261
return ret;
262
}
263
264