summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/dsaparam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr.bin/openssl/dsaparam.c')
-rw-r--r--src/usr.bin/openssl/dsaparam.c414
1 files changed, 414 insertions, 0 deletions
diff --git a/src/usr.bin/openssl/dsaparam.c b/src/usr.bin/openssl/dsaparam.c
new file mode 100644
index 0000000000..5c17a2c9ac
--- /dev/null
+++ b/src/usr.bin/openssl/dsaparam.c
@@ -0,0 +1,414 @@
1/* $OpenBSD: dsaparam.c,v 1.1 2014/08/26 17:47:24 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
60
61/* Until the key-gen callbacks are modified to use newer prototypes, we allow
62 * deprecated functions for openssl-internal code */
63#ifdef OPENSSL_NO_DEPRECATED
64#undef OPENSSL_NO_DEPRECATED
65#endif
66
67
68#include <stdio.h>
69#include <stdlib.h>
70#include <string.h>
71#include <time.h>
72
73#include "apps.h"
74
75#include <openssl/bio.h>
76#include <openssl/bn.h>
77#include <openssl/err.h>
78#include <openssl/dsa.h>
79#include <openssl/pem.h>
80#include <openssl/x509.h>
81
82/* -inform arg - input format - default PEM (DER or PEM)
83 * -outform arg - output format - default PEM
84 * -in arg - input file - default stdin
85 * -out arg - output file - default stdout
86 * -noout
87 * -text
88 * -C
89 * -noout
90 * -genkey
91 * #ifdef GENCB_TEST
92 * -timebomb n - interrupt keygen after <n> seconds
93 * #endif
94 */
95
96#ifdef GENCB_TEST
97
98static int stop_keygen_flag = 0;
99
100static void
101timebomb_sigalarm(int foo)
102{
103 stop_keygen_flag = 1;
104}
105
106#endif
107
108static int dsa_cb(int p, int n, BN_GENCB * cb);
109
110int dsaparam_main(int, char **);
111
112int
113dsaparam_main(int argc, char **argv)
114{
115 DSA *dsa = NULL;
116 int i, badops = 0, text = 0;
117 BIO *in = NULL, *out = NULL;
118 int informat, outformat, noout = 0, C = 0, ret = 1;
119 char *infile, *outfile, *prog;
120 int numbits = -1, num, genkey = 0;
121#ifndef OPENSSL_NO_ENGINE
122 char *engine = NULL;
123#endif
124#ifdef GENCB_TEST
125 const char *errstr = NULL;
126 int timebomb = 0;
127#endif
128
129 infile = NULL;
130 outfile = NULL;
131 informat = FORMAT_PEM;
132 outformat = FORMAT_PEM;
133
134 prog = argv[0];
135 argc--;
136 argv++;
137 while (argc >= 1) {
138 if (strcmp(*argv, "-inform") == 0) {
139 if (--argc < 1)
140 goto bad;
141 informat = str2fmt(*(++argv));
142 } else if (strcmp(*argv, "-outform") == 0) {
143 if (--argc < 1)
144 goto bad;
145 outformat = str2fmt(*(++argv));
146 } else if (strcmp(*argv, "-in") == 0) {
147 if (--argc < 1)
148 goto bad;
149 infile = *(++argv);
150 } else if (strcmp(*argv, "-out") == 0) {
151 if (--argc < 1)
152 goto bad;
153 outfile = *(++argv);
154 }
155#ifndef OPENSSL_NO_ENGINE
156 else if (strcmp(*argv, "-engine") == 0) {
157 if (--argc < 1)
158 goto bad;
159 engine = *(++argv);
160 }
161#endif
162#ifdef GENCB_TEST
163 else if (strcmp(*argv, "-timebomb") == 0) {
164 if (--argc < 1)
165 goto bad;
166 timebomb = strtonum(*(++argv), 0, INT_MAX, &errstr);
167 if (errstr)
168 goto bad;
169 }
170#endif
171 else if (strcmp(*argv, "-text") == 0)
172 text = 1;
173 else if (strcmp(*argv, "-C") == 0)
174 C = 1;
175 else if (strcmp(*argv, "-genkey") == 0) {
176 genkey = 1;
177 } else if (strcmp(*argv, "-noout") == 0)
178 noout = 1;
179 else if (sscanf(*argv, "%d", &num) == 1) {
180 /* generate a key */
181 numbits = num;
182 } else {
183 BIO_printf(bio_err, "unknown option %s\n", *argv);
184 badops = 1;
185 break;
186 }
187 argc--;
188 argv++;
189 }
190
191 if (badops) {
192bad:
193 BIO_printf(bio_err, "%s [options] [bits] <infile >outfile\n", prog);
194 BIO_printf(bio_err, "where options are\n");
195 BIO_printf(bio_err, " -inform arg input format - DER or PEM\n");
196 BIO_printf(bio_err, " -outform arg output format - DER or PEM\n");
197 BIO_printf(bio_err, " -in arg input file\n");
198 BIO_printf(bio_err, " -out arg output file\n");
199 BIO_printf(bio_err, " -text print as text\n");
200 BIO_printf(bio_err, " -C Output C code\n");
201 BIO_printf(bio_err, " -noout no output\n");
202 BIO_printf(bio_err, " -genkey generate a DSA key\n");
203#ifndef OPENSSL_NO_ENGINE
204 BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n");
205#endif
206#ifdef GENCB_TEST
207 BIO_printf(bio_err, " -timebomb n interrupt keygen after <n> seconds\n");
208#endif
209 BIO_printf(bio_err, " number number of bits to use for generating private key\n");
210 goto end;
211 }
212 ERR_load_crypto_strings();
213
214 in = BIO_new(BIO_s_file());
215 out = BIO_new(BIO_s_file());
216 if ((in == NULL) || (out == NULL)) {
217 ERR_print_errors(bio_err);
218 goto end;
219 }
220 if (infile == NULL)
221 BIO_set_fp(in, stdin, BIO_NOCLOSE);
222 else {
223 if (BIO_read_filename(in, infile) <= 0) {
224 perror(infile);
225 goto end;
226 }
227 }
228 if (outfile == NULL) {
229 BIO_set_fp(out, stdout, BIO_NOCLOSE);
230 } else {
231 if (BIO_write_filename(out, outfile) <= 0) {
232 perror(outfile);
233 goto end;
234 }
235 }
236
237#ifndef OPENSSL_NO_ENGINE
238 setup_engine(bio_err, engine, 0);
239#endif
240
241 if (numbits > 0) {
242 BN_GENCB cb;
243 BN_GENCB_set(&cb, dsa_cb, bio_err);
244 dsa = DSA_new();
245 if (!dsa) {
246 BIO_printf(bio_err, "Error allocating DSA object\n");
247 goto end;
248 }
249 BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
250 BIO_printf(bio_err, "This could take some time\n");
251#ifdef GENCB_TEST
252 if (timebomb > 0) {
253 struct sigaction act;
254 act.sa_handler = timebomb_sigalarm;
255 act.sa_flags = 0;
256 BIO_printf(bio_err, "(though I'll stop it if not done within %d secs)\n",
257 timebomb);
258 if (sigaction(SIGALRM, &act, NULL) != 0) {
259 BIO_printf(bio_err, "Error, couldn't set SIGALRM handler\n");
260 goto end;
261 }
262 alarm(timebomb);
263 }
264#endif
265 if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) {
266#ifdef GENCB_TEST
267 if (stop_keygen_flag) {
268 BIO_printf(bio_err, "DSA key generation time-stopped\n");
269 /* This is an asked-for behaviour! */
270 ret = 0;
271 goto end;
272 }
273#endif
274 ERR_print_errors(bio_err);
275 BIO_printf(bio_err, "Error, DSA key generation failed\n");
276 goto end;
277 }
278 } else if (informat == FORMAT_ASN1)
279 dsa = d2i_DSAparams_bio(in, NULL);
280 else if (informat == FORMAT_PEM)
281 dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
282 else {
283 BIO_printf(bio_err, "bad input format specified\n");
284 goto end;
285 }
286 if (dsa == NULL) {
287 BIO_printf(bio_err, "unable to load DSA parameters\n");
288 ERR_print_errors(bio_err);
289 goto end;
290 }
291 if (text) {
292 DSAparams_print(out, dsa);
293 }
294 if (C) {
295 unsigned char *data;
296 int l, len, bits_p;
297
298 len = BN_num_bytes(dsa->p);
299 bits_p = BN_num_bits(dsa->p);
300 data = malloc(len + 20);
301 if (data == NULL) {
302 perror("malloc");
303 goto end;
304 }
305 l = BN_bn2bin(dsa->p, data);
306 printf("static unsigned char dsa%d_p[] = {", bits_p);
307 for (i = 0; i < l; i++) {
308 if ((i % 12) == 0)
309 printf("\n\t");
310 printf("0x%02X, ", data[i]);
311 }
312 printf("\n\t};\n");
313
314 l = BN_bn2bin(dsa->q, data);
315 printf("static unsigned char dsa%d_q[] = {", bits_p);
316 for (i = 0; i < l; i++) {
317 if ((i % 12) == 0)
318 printf("\n\t");
319 printf("0x%02X, ", data[i]);
320 }
321 printf("\n\t};\n");
322
323 l = BN_bn2bin(dsa->g, data);
324 printf("static unsigned char dsa%d_g[] = {", bits_p);
325 for (i = 0; i < l; i++) {
326 if ((i % 12) == 0)
327 printf("\n\t");
328 printf("0x%02X, ", data[i]);
329 }
330 free(data);
331 printf("\n\t};\n\n");
332
333 printf("DSA *get_dsa%d()\n\t{\n", bits_p);
334 printf("\tDSA *dsa;\n\n");
335 printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n");
336 printf("\tdsa->p = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n",
337 bits_p, bits_p);
338 printf("\tdsa->q = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n",
339 bits_p, bits_p);
340 printf("\tdsa->g = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n",
341 bits_p, bits_p);
342 printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
343 printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
344 printf("\treturn(dsa);\n\t}\n");
345 }
346 if (!noout) {
347 if (outformat == FORMAT_ASN1)
348 i = i2d_DSAparams_bio(out, dsa);
349 else if (outformat == FORMAT_PEM)
350 i = PEM_write_bio_DSAparams(out, dsa);
351 else {
352 BIO_printf(bio_err, "bad output format specified for outfile\n");
353 goto end;
354 }
355 if (!i) {
356 BIO_printf(bio_err, "unable to write DSA parameters\n");
357 ERR_print_errors(bio_err);
358 goto end;
359 }
360 }
361 if (genkey) {
362 DSA *dsakey;
363
364 if ((dsakey = DSAparams_dup(dsa)) == NULL)
365 goto end;
366 if (!DSA_generate_key(dsakey)) {
367 ERR_print_errors(bio_err);
368 DSA_free(dsakey);
369 goto end;
370 }
371 if (outformat == FORMAT_ASN1)
372 i = i2d_DSAPrivateKey_bio(out, dsakey);
373 else if (outformat == FORMAT_PEM)
374 i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
375 else {
376 BIO_printf(bio_err, "bad output format specified for outfile\n");
377 DSA_free(dsakey);
378 goto end;
379 }
380 DSA_free(dsakey);
381 }
382 ret = 0;
383
384end:
385 BIO_free(in);
386 if (out != NULL)
387 BIO_free_all(out);
388 if (dsa != NULL)
389 DSA_free(dsa);
390
391 return (ret);
392}
393
394static int
395dsa_cb(int p, int n, BN_GENCB * cb)
396{
397 char c = '*';
398
399 if (p == 0)
400 c = '.';
401 if (p == 1)
402 c = '+';
403 if (p == 2)
404 c = '*';
405 if (p == 3)
406 c = '\n';
407 BIO_write(cb->arg, &c, 1);
408 (void) BIO_flush(cb->arg);
409#ifdef GENCB_TEST
410 if (stop_keygen_flag)
411 return 0;
412#endif
413 return 1;
414}