1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: gendsa.c,v 1.15 2022/01/14 09:25:00 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino * All rights reserved.
4f5b1c8a1SJohn Marino *
5f5b1c8a1SJohn Marino * This package is an SSL implementation written
6f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino *
9f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions
11f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino *
16f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino * the code are not to be removed.
18f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino *
23f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino * are met:
26f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino * must display the following acknowledgement:
33f5b1c8a1SJohn Marino * "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino * being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino *
41f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino * SUCH DAMAGE.
52f5b1c8a1SJohn Marino *
53f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be
55f5b1c8a1SJohn Marino * copied and put under another distribution licence
56f5b1c8a1SJohn Marino * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino */
58f5b1c8a1SJohn Marino
59f5b1c8a1SJohn Marino #include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
60f5b1c8a1SJohn Marino
61f5b1c8a1SJohn Marino
62f5b1c8a1SJohn Marino #include <sys/types.h>
63f5b1c8a1SJohn Marino #include <sys/stat.h>
64f5b1c8a1SJohn Marino
65f5b1c8a1SJohn Marino #include <stdio.h>
66f5b1c8a1SJohn Marino #include <string.h>
67f5b1c8a1SJohn Marino
68f5b1c8a1SJohn Marino #include "apps.h"
69f5b1c8a1SJohn Marino
70f5b1c8a1SJohn Marino #include <openssl/bio.h>
71f5b1c8a1SJohn Marino #include <openssl/bn.h>
72f5b1c8a1SJohn Marino #include <openssl/dsa.h>
73f5b1c8a1SJohn Marino #include <openssl/err.h>
74f5b1c8a1SJohn Marino #include <openssl/pem.h>
75f5b1c8a1SJohn Marino #include <openssl/x509.h>
76f5b1c8a1SJohn Marino
77cca6fc52SDaniel Fojt static struct {
78cca6fc52SDaniel Fojt const EVP_CIPHER *enc;
79cca6fc52SDaniel Fojt char *outfile;
80cca6fc52SDaniel Fojt char *passargout;
81cca6fc52SDaniel Fojt } gendsa_config;
82cca6fc52SDaniel Fojt
get_cipher_by_name(char * name)83cca6fc52SDaniel Fojt static const EVP_CIPHER *get_cipher_by_name(char *name)
84cca6fc52SDaniel Fojt {
85cca6fc52SDaniel Fojt if (name == NULL || strcmp(name, "") == 0)
86cca6fc52SDaniel Fojt return (NULL);
87cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_AES
88cca6fc52SDaniel Fojt else if (strcmp(name, "aes128") == 0)
89cca6fc52SDaniel Fojt return EVP_aes_128_cbc();
90cca6fc52SDaniel Fojt else if (strcmp(name, "aes192") == 0)
91cca6fc52SDaniel Fojt return EVP_aes_192_cbc();
92cca6fc52SDaniel Fojt else if (strcmp(name, "aes256") == 0)
93cca6fc52SDaniel Fojt return EVP_aes_256_cbc();
94cca6fc52SDaniel Fojt #endif
95cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_CAMELLIA
96cca6fc52SDaniel Fojt else if (strcmp(name, "camellia128") == 0)
97cca6fc52SDaniel Fojt return EVP_camellia_128_cbc();
98cca6fc52SDaniel Fojt else if (strcmp(name, "camellia192") == 0)
99cca6fc52SDaniel Fojt return EVP_camellia_192_cbc();
100cca6fc52SDaniel Fojt else if (strcmp(name, "camellia256") == 0)
101cca6fc52SDaniel Fojt return EVP_camellia_256_cbc();
102cca6fc52SDaniel Fojt #endif
103cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_DES
104cca6fc52SDaniel Fojt else if (strcmp(name, "des") == 0)
105cca6fc52SDaniel Fojt return EVP_des_cbc();
106cca6fc52SDaniel Fojt else if (strcmp(name, "des3") == 0)
107cca6fc52SDaniel Fojt return EVP_des_ede3_cbc();
108cca6fc52SDaniel Fojt #endif
109cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_IDEA
110cca6fc52SDaniel Fojt else if (strcmp(name, "idea") == 0)
111cca6fc52SDaniel Fojt return EVP_idea_cbc();
112cca6fc52SDaniel Fojt #endif
113cca6fc52SDaniel Fojt else
114cca6fc52SDaniel Fojt return (NULL);
115cca6fc52SDaniel Fojt }
116cca6fc52SDaniel Fojt
117cca6fc52SDaniel Fojt static int
set_enc(int argc,char ** argv,int * argsused)118cca6fc52SDaniel Fojt set_enc(int argc, char **argv, int *argsused)
119cca6fc52SDaniel Fojt {
120cca6fc52SDaniel Fojt char *name = argv[0];
121cca6fc52SDaniel Fojt
122cca6fc52SDaniel Fojt if (*name++ != '-')
123cca6fc52SDaniel Fojt return (1);
124cca6fc52SDaniel Fojt
125cca6fc52SDaniel Fojt if ((gendsa_config.enc = get_cipher_by_name(name)) == NULL)
126cca6fc52SDaniel Fojt return (1);
127cca6fc52SDaniel Fojt
128cca6fc52SDaniel Fojt *argsused = 1;
129cca6fc52SDaniel Fojt return (0);
130cca6fc52SDaniel Fojt }
131cca6fc52SDaniel Fojt
132cca6fc52SDaniel Fojt static const struct option gendsa_options[] = {
133cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_AES
134cca6fc52SDaniel Fojt {
135cca6fc52SDaniel Fojt .name = "aes128",
136cca6fc52SDaniel Fojt .desc = "Encrypt PEM output with CBC AES",
137cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
138cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
139cca6fc52SDaniel Fojt },
140cca6fc52SDaniel Fojt {
141cca6fc52SDaniel Fojt .name = "aes192",
142cca6fc52SDaniel Fojt .desc = "Encrypt PEM output with CBC AES",
143cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
144cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
145cca6fc52SDaniel Fojt },
146cca6fc52SDaniel Fojt {
147cca6fc52SDaniel Fojt .name = "aes256",
148cca6fc52SDaniel Fojt .desc = "Encrypt PEM output with CBC AES",
149cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
150cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
151cca6fc52SDaniel Fojt },
152cca6fc52SDaniel Fojt #endif
153cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_CAMELLIA
154cca6fc52SDaniel Fojt {
155cca6fc52SDaniel Fojt .name = "camellia128",
156cca6fc52SDaniel Fojt .desc = "Encrypt PEM output with CBC Camellia",
157cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
158cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
159cca6fc52SDaniel Fojt },
160cca6fc52SDaniel Fojt {
161cca6fc52SDaniel Fojt .name = "camellia192",
162cca6fc52SDaniel Fojt .desc = "Encrypt PEM output with CBC Camellia",
163cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
164cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
165cca6fc52SDaniel Fojt },
166cca6fc52SDaniel Fojt {
167cca6fc52SDaniel Fojt .name = "camellia256",
168cca6fc52SDaniel Fojt .desc = "Encrypt PEM output with CBC Camellia",
169cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
170cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
171cca6fc52SDaniel Fojt },
172cca6fc52SDaniel Fojt #endif
173cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_DES
174cca6fc52SDaniel Fojt {
175cca6fc52SDaniel Fojt .name = "des",
176cca6fc52SDaniel Fojt .desc = "Encrypt the generated key with DES in CBC mode",
177cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
178cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
179cca6fc52SDaniel Fojt },
180cca6fc52SDaniel Fojt {
181cca6fc52SDaniel Fojt .name = "des3",
182cca6fc52SDaniel Fojt .desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
183cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
184cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
185cca6fc52SDaniel Fojt },
186cca6fc52SDaniel Fojt #endif
187cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_IDEA
188cca6fc52SDaniel Fojt {
189cca6fc52SDaniel Fojt .name = "idea",
190cca6fc52SDaniel Fojt .desc = "Encrypt the generated key with IDEA in CBC mode",
191cca6fc52SDaniel Fojt .type = OPTION_ARGV_FUNC,
192cca6fc52SDaniel Fojt .opt.argvfunc = set_enc,
193cca6fc52SDaniel Fojt },
194cca6fc52SDaniel Fojt #endif
195cca6fc52SDaniel Fojt {
196cca6fc52SDaniel Fojt .name = "out",
197cca6fc52SDaniel Fojt .argname = "file",
198cca6fc52SDaniel Fojt .desc = "Output the key to 'file'",
199cca6fc52SDaniel Fojt .type = OPTION_ARG,
200cca6fc52SDaniel Fojt .opt.arg = &gendsa_config.outfile,
201cca6fc52SDaniel Fojt },
202cca6fc52SDaniel Fojt {
203cca6fc52SDaniel Fojt .name = "passout",
204cca6fc52SDaniel Fojt .argname = "src",
205cca6fc52SDaniel Fojt .desc = "Output file passphrase source",
206cca6fc52SDaniel Fojt .type = OPTION_ARG,
207cca6fc52SDaniel Fojt .opt.arg = &gendsa_config.passargout,
208cca6fc52SDaniel Fojt },
209cca6fc52SDaniel Fojt { NULL },
210cca6fc52SDaniel Fojt };
211cca6fc52SDaniel Fojt
212cca6fc52SDaniel Fojt static void
gendsa_usage(void)213cca6fc52SDaniel Fojt gendsa_usage(void)
214cca6fc52SDaniel Fojt {
215cca6fc52SDaniel Fojt fprintf(stderr, "usage: gendsa [-aes128 | -aes192 | -aes256 |\n");
216cca6fc52SDaniel Fojt fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |\n");
217cca6fc52SDaniel Fojt fprintf(stderr, " -des | -des3 | -idea] [-out file] [-passout src]");
218cca6fc52SDaniel Fojt fprintf(stderr, " paramfile\n\n");
219cca6fc52SDaniel Fojt options_usage(gendsa_options);
220cca6fc52SDaniel Fojt fprintf(stderr, "\n");
221cca6fc52SDaniel Fojt }
222cca6fc52SDaniel Fojt
223f5b1c8a1SJohn Marino int
gendsa_main(int argc,char ** argv)224f5b1c8a1SJohn Marino gendsa_main(int argc, char **argv)
225f5b1c8a1SJohn Marino {
226f5b1c8a1SJohn Marino DSA *dsa = NULL;
227f5b1c8a1SJohn Marino int ret = 1;
228f5b1c8a1SJohn Marino char *dsaparams = NULL;
229cca6fc52SDaniel Fojt char *passout = NULL;
230f5b1c8a1SJohn Marino BIO *out = NULL, *in = NULL;
231f5b1c8a1SJohn Marino
232f5b1c8a1SJohn Marino if (single_execution) {
23372c33676SMaxim Ag if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
234f5b1c8a1SJohn Marino perror("pledge");
235f5b1c8a1SJohn Marino exit(1);
236f5b1c8a1SJohn Marino }
237f5b1c8a1SJohn Marino }
238f5b1c8a1SJohn Marino
239cca6fc52SDaniel Fojt memset(&gendsa_config, 0, sizeof(gendsa_config));
240cca6fc52SDaniel Fojt
241cca6fc52SDaniel Fojt if (options_parse(argc, argv, gendsa_options, &dsaparams, NULL) != 0) {
242cca6fc52SDaniel Fojt gendsa_usage();
243cca6fc52SDaniel Fojt goto end;
244f5b1c8a1SJohn Marino }
245f5b1c8a1SJohn Marino
246f5b1c8a1SJohn Marino if (dsaparams == NULL) {
247cca6fc52SDaniel Fojt gendsa_usage();
248f5b1c8a1SJohn Marino goto end;
249f5b1c8a1SJohn Marino }
250cca6fc52SDaniel Fojt if (!app_passwd(bio_err, NULL, gendsa_config.passargout, NULL,
251cca6fc52SDaniel Fojt &passout)) {
252f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error getting password\n");
253f5b1c8a1SJohn Marino goto end;
254f5b1c8a1SJohn Marino }
255f5b1c8a1SJohn Marino in = BIO_new(BIO_s_file());
256f5b1c8a1SJohn Marino if (!(BIO_read_filename(in, dsaparams))) {
257f5b1c8a1SJohn Marino perror(dsaparams);
258f5b1c8a1SJohn Marino goto end;
259f5b1c8a1SJohn Marino }
260f5b1c8a1SJohn Marino if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) {
261f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to load DSA parameter file\n");
262f5b1c8a1SJohn Marino goto end;
263f5b1c8a1SJohn Marino }
264f5b1c8a1SJohn Marino BIO_free(in);
265f5b1c8a1SJohn Marino in = NULL;
266f5b1c8a1SJohn Marino
267f5b1c8a1SJohn Marino out = BIO_new(BIO_s_file());
268f5b1c8a1SJohn Marino if (out == NULL)
269f5b1c8a1SJohn Marino goto end;
270f5b1c8a1SJohn Marino
271cca6fc52SDaniel Fojt if (gendsa_config.outfile == NULL) {
272f5b1c8a1SJohn Marino BIO_set_fp(out, stdout, BIO_NOCLOSE);
273f5b1c8a1SJohn Marino } else {
274cca6fc52SDaniel Fojt if (BIO_write_filename(out, gendsa_config.outfile) <= 0) {
275cca6fc52SDaniel Fojt perror(gendsa_config.outfile);
276f5b1c8a1SJohn Marino goto end;
277f5b1c8a1SJohn Marino }
278f5b1c8a1SJohn Marino }
279f5b1c8a1SJohn Marino
280f5b1c8a1SJohn Marino BIO_printf(bio_err, "Generating DSA key, %d bits\n",
281*de0e0e4dSAntonio Huete Jimenez BN_num_bits(DSA_get0_p(dsa)));
282f5b1c8a1SJohn Marino if (!DSA_generate_key(dsa))
283f5b1c8a1SJohn Marino goto end;
284f5b1c8a1SJohn Marino
285cca6fc52SDaniel Fojt if (!PEM_write_bio_DSAPrivateKey(out, dsa, gendsa_config.enc, NULL, 0,
286cca6fc52SDaniel Fojt NULL, passout))
287f5b1c8a1SJohn Marino goto end;
288f5b1c8a1SJohn Marino ret = 0;
289f5b1c8a1SJohn Marino end:
290f5b1c8a1SJohn Marino if (ret != 0)
291f5b1c8a1SJohn Marino ERR_print_errors(bio_err);
292f5b1c8a1SJohn Marino BIO_free(in);
293f5b1c8a1SJohn Marino BIO_free_all(out);
294f5b1c8a1SJohn Marino DSA_free(dsa);
295f5b1c8a1SJohn Marino free(passout);
296f5b1c8a1SJohn Marino
297f5b1c8a1SJohn Marino return (ret);
298f5b1c8a1SJohn Marino }
299