Branch data Line data Source code
1 : : /* apps/dsaparam.c */
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 : : /* Until the key-gen callbacks are modified to use newer prototypes, we allow
61 : : * deprecated functions for openssl-internal code */
62 : : #ifdef OPENSSL_NO_DEPRECATED
63 : : #undef OPENSSL_NO_DEPRECATED
64 : : #endif
65 : :
66 : : #ifndef OPENSSL_NO_DSA
67 : : #include <assert.h>
68 : : #include <stdio.h>
69 : : #include <stdlib.h>
70 : : #include <time.h>
71 : : #include <string.h>
72 : : #include "apps.h"
73 : : #include <openssl/bio.h>
74 : : #include <openssl/err.h>
75 : : #include <openssl/bn.h>
76 : : #include <openssl/dsa.h>
77 : : #include <openssl/x509.h>
78 : : #include <openssl/pem.h>
79 : :
80 : : #undef PROG
81 : : #define PROG dsaparam_main
82 : :
83 : : /* -inform arg - input format - default PEM (DER or PEM)
84 : : * -outform arg - output format - default PEM
85 : : * -in arg - input file - default stdin
86 : : * -out arg - output file - default stdout
87 : : * -noout
88 : : * -text
89 : : * -C
90 : : * -noout
91 : : * -genkey
92 : : * #ifdef GENCB_TEST
93 : : * -timebomb n - interrupt keygen after <n> seconds
94 : : * #endif
95 : : */
96 : :
97 : : #ifdef GENCB_TEST
98 : :
99 : : static int stop_keygen_flag = 0;
100 : :
101 : : static void timebomb_sigalarm(int foo)
102 : : {
103 : : stop_keygen_flag = 1;
104 : : }
105 : :
106 : : #endif
107 : :
108 : : static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
109 : :
110 : : int MAIN(int, char **);
111 : :
112 : 0 : int MAIN(int argc, char **argv)
113 : : {
114 : 0 : DSA *dsa=NULL;
115 : 0 : int i,badops=0,text=0;
116 : 0 : BIO *in=NULL,*out=NULL;
117 : 0 : int informat,outformat,noout=0,C=0,ret=1;
118 : 0 : char *infile,*outfile,*prog,*inrand=NULL;
119 : 0 : int numbits= -1,num,genkey=0;
120 : 0 : int need_rand=0;
121 : 0 : int non_fips_allow = 0;
122 : : #ifndef OPENSSL_NO_ENGINE
123 : 0 : char *engine=NULL;
124 : : #endif
125 : : #ifdef GENCB_TEST
126 : : int timebomb=0;
127 : : #endif
128 : :
129 : 0 : apps_startup();
130 : :
131 [ # # ]: 0 : if (bio_err == NULL)
132 [ # # ]: 0 : if ((bio_err=BIO_new(BIO_s_file())) != NULL)
133 : 0 : BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
134 : :
135 [ # # ]: 0 : if (!load_config(bio_err, NULL))
136 : : goto end;
137 : :
138 : 0 : infile=NULL;
139 : 0 : outfile=NULL;
140 : 0 : informat=FORMAT_PEM;
141 : 0 : outformat=FORMAT_PEM;
142 : :
143 : 0 : prog=argv[0];
144 : 0 : argc--;
145 : 0 : argv++;
146 [ # # ]: 0 : while (argc >= 1)
147 : : {
148 [ # # ]: 0 : if (strcmp(*argv,"-inform") == 0)
149 : : {
150 [ # # ]: 0 : if (--argc < 1) goto bad;
151 : 0 : informat=str2fmt(*(++argv));
152 : : }
153 [ # # ]: 0 : else if (strcmp(*argv,"-outform") == 0)
154 : : {
155 [ # # ]: 0 : if (--argc < 1) goto bad;
156 : 0 : outformat=str2fmt(*(++argv));
157 : : }
158 [ # # ]: 0 : else if (strcmp(*argv,"-in") == 0)
159 : : {
160 [ # # ]: 0 : if (--argc < 1) goto bad;
161 : 0 : infile= *(++argv);
162 : : }
163 [ # # ]: 0 : else if (strcmp(*argv,"-out") == 0)
164 : : {
165 [ # # ]: 0 : if (--argc < 1) goto bad;
166 : 0 : outfile= *(++argv);
167 : : }
168 : : #ifndef OPENSSL_NO_ENGINE
169 [ # # ]: 0 : else if(strcmp(*argv, "-engine") == 0)
170 : : {
171 [ # # ]: 0 : if (--argc < 1) goto bad;
172 : 0 : engine = *(++argv);
173 : : }
174 : : #endif
175 : : #ifdef GENCB_TEST
176 : : else if(strcmp(*argv, "-timebomb") == 0)
177 : : {
178 : : if (--argc < 1) goto bad;
179 : : timebomb = atoi(*(++argv));
180 : : }
181 : : #endif
182 [ # # ]: 0 : else if (strcmp(*argv,"-text") == 0)
183 : : text=1;
184 [ # # ]: 0 : else if (strcmp(*argv,"-C") == 0)
185 : : C=1;
186 [ # # ]: 0 : else if (strcmp(*argv,"-genkey") == 0)
187 : : {
188 : : genkey=1;
189 : : need_rand=1;
190 : : }
191 [ # # ]: 0 : else if (strcmp(*argv,"-rand") == 0)
192 : : {
193 [ # # ]: 0 : if (--argc < 1) goto bad;
194 : 0 : inrand= *(++argv);
195 : 0 : need_rand=1;
196 : : }
197 [ # # ]: 0 : else if (strcmp(*argv,"-noout") == 0)
198 : : noout=1;
199 [ # # ]: 0 : else if (strcmp(*argv,"-non-fips-allow") == 0)
200 : : non_fips_allow = 1;
201 [ # # ]: 0 : else if (sscanf(*argv,"%d",&num) == 1)
202 : : {
203 : : /* generate a key */
204 : 0 : numbits=num;
205 : 0 : need_rand=1;
206 : : }
207 : : else
208 : : {
209 : 0 : BIO_printf(bio_err,"unknown option %s\n",*argv);
210 : 0 : badops=1;
211 : 0 : break;
212 : : }
213 : 0 : argc--;
214 : 0 : argv++;
215 : : }
216 : :
217 [ # # ]: 0 : if (badops)
218 : : {
219 : : bad:
220 : 0 : BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
221 : 0 : BIO_printf(bio_err,"where options are\n");
222 : 0 : BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
223 : 0 : BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
224 : 0 : BIO_printf(bio_err," -in arg input file\n");
225 : 0 : BIO_printf(bio_err," -out arg output file\n");
226 : 0 : BIO_printf(bio_err," -text print as text\n");
227 : 0 : BIO_printf(bio_err," -C Output C code\n");
228 : 0 : BIO_printf(bio_err," -noout no output\n");
229 : 0 : BIO_printf(bio_err," -genkey generate a DSA key\n");
230 : 0 : BIO_printf(bio_err," -rand files to use for random number input\n");
231 : : #ifndef OPENSSL_NO_ENGINE
232 : 0 : BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
233 : : #endif
234 : : #ifdef GENCB_TEST
235 : : BIO_printf(bio_err," -timebomb n interrupt keygen after <n> seconds\n");
236 : : #endif
237 : 0 : BIO_printf(bio_err," number number of bits to use for generating private key\n");
238 : 0 : goto end;
239 : : }
240 : :
241 : 0 : ERR_load_crypto_strings();
242 : :
243 : 0 : in=BIO_new(BIO_s_file());
244 : 0 : out=BIO_new(BIO_s_file());
245 [ # # ]: 0 : if ((in == NULL) || (out == NULL))
246 : : {
247 : 0 : ERR_print_errors(bio_err);
248 : 0 : goto end;
249 : : }
250 : :
251 [ # # ]: 0 : if (infile == NULL)
252 : 0 : BIO_set_fp(in,stdin,BIO_NOCLOSE);
253 : : else
254 : : {
255 [ # # ]: 0 : if (BIO_read_filename(in,infile) <= 0)
256 : : {
257 : 0 : perror(infile);
258 : 0 : goto end;
259 : : }
260 : : }
261 [ # # ]: 0 : if (outfile == NULL)
262 : : {
263 : 0 : BIO_set_fp(out,stdout,BIO_NOCLOSE);
264 : : #ifdef OPENSSL_SYS_VMS
265 : : {
266 : : BIO *tmpbio = BIO_new(BIO_f_linebuffer());
267 : : out = BIO_push(tmpbio, out);
268 : : }
269 : : #endif
270 : : }
271 : : else
272 : : {
273 [ # # ]: 0 : if (BIO_write_filename(out,outfile) <= 0)
274 : : {
275 : 0 : perror(outfile);
276 : 0 : goto end;
277 : : }
278 : : }
279 : :
280 : : #ifndef OPENSSL_NO_ENGINE
281 : 0 : setup_engine(bio_err, engine, 0);
282 : : #endif
283 : :
284 [ # # ]: 0 : if (need_rand)
285 : : {
286 : 0 : app_RAND_load_file(NULL, bio_err, (inrand != NULL));
287 [ # # ]: 0 : if (inrand != NULL)
288 : 0 : BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
289 : : app_RAND_load_files(inrand));
290 : : }
291 : :
292 [ # # ]: 0 : if (numbits > 0)
293 : : {
294 : : BN_GENCB cb;
295 : 0 : BN_GENCB_set(&cb, dsa_cb, bio_err);
296 [ # # ]: 0 : assert(need_rand);
297 : 0 : dsa = DSA_new();
298 [ # # ]: 0 : if(!dsa)
299 : : {
300 : 0 : BIO_printf(bio_err,"Error allocating DSA object\n");
301 : 0 : goto end;
302 : : }
303 [ # # ]: 0 : if (non_fips_allow)
304 : 0 : dsa->flags |= DSA_FLAG_NON_FIPS_ALLOW;
305 : 0 : BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
306 : 0 : BIO_printf(bio_err,"This could take some time\n");
307 : : #ifdef GENCB_TEST
308 : : if(timebomb > 0)
309 : : {
310 : : struct sigaction act;
311 : : act.sa_handler = timebomb_sigalarm;
312 : : act.sa_flags = 0;
313 : : BIO_printf(bio_err,"(though I'll stop it if not done within %d secs)\n",
314 : : timebomb);
315 : : if(sigaction(SIGALRM, &act, NULL) != 0)
316 : : {
317 : : BIO_printf(bio_err,"Error, couldn't set SIGALRM handler\n");
318 : : goto end;
319 : : }
320 : : alarm(timebomb);
321 : : }
322 : : #endif
323 [ # # ]: 0 : if(!DSA_generate_parameters_ex(dsa,num,NULL,0,NULL,NULL, &cb))
324 : : {
325 : : #ifdef GENCB_TEST
326 : : if(stop_keygen_flag)
327 : : {
328 : : BIO_printf(bio_err,"DSA key generation time-stopped\n");
329 : : /* This is an asked-for behaviour! */
330 : : ret = 0;
331 : : goto end;
332 : : }
333 : : #endif
334 : 0 : ERR_print_errors(bio_err);
335 : 0 : BIO_printf(bio_err,"Error, DSA key generation failed\n");
336 : 0 : goto end;
337 : : }
338 : : }
339 [ # # ]: 0 : else if (informat == FORMAT_ASN1)
340 : 0 : dsa=d2i_DSAparams_bio(in,NULL);
341 [ # # ]: 0 : else if (informat == FORMAT_PEM)
342 : 0 : dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
343 : : else
344 : : {
345 : 0 : BIO_printf(bio_err,"bad input format specified\n");
346 : 0 : goto end;
347 : : }
348 [ # # ]: 0 : if (dsa == NULL)
349 : : {
350 : 0 : BIO_printf(bio_err,"unable to load DSA parameters\n");
351 : 0 : ERR_print_errors(bio_err);
352 : 0 : goto end;
353 : : }
354 : :
355 [ # # ]: 0 : if (text)
356 : : {
357 : 0 : DSAparams_print(out,dsa);
358 : : }
359 : :
360 [ # # ]: 0 : if (C)
361 : : {
362 : : unsigned char *data;
363 : : int l,len,bits_p;
364 : :
365 : 0 : len=BN_num_bytes(dsa->p);
366 : 0 : bits_p=BN_num_bits(dsa->p);
367 : 0 : data=(unsigned char *)OPENSSL_malloc(len+20);
368 [ # # ]: 0 : if (data == NULL)
369 : : {
370 : 0 : perror("OPENSSL_malloc");
371 : 0 : goto end;
372 : : }
373 : 0 : l=BN_bn2bin(dsa->p,data);
374 : : printf("static unsigned char dsa%d_p[]={",bits_p);
375 [ # # ]: 0 : for (i=0; i<l; i++)
376 : : {
377 [ # # ]: 0 : if ((i%12) == 0) printf("\n\t");
378 : 0 : printf("0x%02X,",data[i]);
379 : : }
380 : : printf("\n\t};\n");
381 : :
382 : 0 : l=BN_bn2bin(dsa->q,data);
383 : : printf("static unsigned char dsa%d_q[]={",bits_p);
384 [ # # ]: 0 : for (i=0; i<l; i++)
385 : : {
386 [ # # ]: 0 : if ((i%12) == 0) printf("\n\t");
387 : 0 : printf("0x%02X,",data[i]);
388 : : }
389 : : printf("\n\t};\n");
390 : :
391 : 0 : l=BN_bn2bin(dsa->g,data);
392 : : printf("static unsigned char dsa%d_g[]={",bits_p);
393 [ # # ]: 0 : for (i=0; i<l; i++)
394 : : {
395 [ # # ]: 0 : if ((i%12) == 0) printf("\n\t");
396 : 0 : printf("0x%02X,",data[i]);
397 : : }
398 : : printf("\n\t};\n\n");
399 : :
400 : : printf("DSA *get_dsa%d()\n\t{\n",bits_p);
401 : : printf("\tDSA *dsa;\n\n");
402 : : printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n");
403 : : printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n",
404 : : bits_p,bits_p);
405 : : printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n",
406 : : bits_p,bits_p);
407 : : printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n",
408 : : bits_p,bits_p);
409 : : printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
410 : : printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
411 : : printf("\treturn(dsa);\n\t}\n");
412 : : }
413 : :
414 : :
415 [ # # ]: 0 : if (!noout)
416 : : {
417 [ # # ]: 0 : if (outformat == FORMAT_ASN1)
418 : 0 : i=i2d_DSAparams_bio(out,dsa);
419 [ # # ]: 0 : else if (outformat == FORMAT_PEM)
420 : 0 : i=PEM_write_bio_DSAparams(out,dsa);
421 : : else {
422 : 0 : BIO_printf(bio_err,"bad output format specified for outfile\n");
423 : 0 : goto end;
424 : : }
425 [ # # ]: 0 : if (!i)
426 : : {
427 : 0 : BIO_printf(bio_err,"unable to write DSA parameters\n");
428 : 0 : ERR_print_errors(bio_err);
429 : 0 : goto end;
430 : : }
431 : : }
432 [ # # ]: 0 : if (genkey)
433 : : {
434 : : DSA *dsakey;
435 : :
436 [ # # ]: 0 : assert(need_rand);
437 [ # # ]: 0 : if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
438 [ # # ]: 0 : if (non_fips_allow)
439 : 0 : dsakey->flags |= DSA_FLAG_NON_FIPS_ALLOW;
440 [ # # ]: 0 : if (!DSA_generate_key(dsakey))
441 : : {
442 : 0 : ERR_print_errors(bio_err);
443 : 0 : DSA_free(dsakey);
444 : 0 : goto end;
445 : : }
446 [ # # ]: 0 : if (outformat == FORMAT_ASN1)
447 : 0 : i=i2d_DSAPrivateKey_bio(out,dsakey);
448 [ # # ]: 0 : else if (outformat == FORMAT_PEM)
449 : 0 : i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
450 : : else {
451 : 0 : BIO_printf(bio_err,"bad output format specified for outfile\n");
452 : 0 : DSA_free(dsakey);
453 : 0 : goto end;
454 : : }
455 : 0 : DSA_free(dsakey);
456 : : }
457 [ # # ]: 0 : if (need_rand)
458 : 0 : app_RAND_write_file(NULL, bio_err);
459 : : ret=0;
460 : : end:
461 [ # # ]: 0 : if (in != NULL) BIO_free(in);
462 [ # # ]: 0 : if (out != NULL) BIO_free_all(out);
463 [ # # ]: 0 : if (dsa != NULL) DSA_free(dsa);
464 : : apps_shutdown();
465 : 0 : OPENSSL_EXIT(ret);
466 : : }
467 : :
468 : 0 : static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
469 : : {
470 : 0 : char c='*';
471 : :
472 [ # # ]: 0 : if (p == 0) c='.';
473 [ # # ]: 0 : if (p == 1) c='+';
474 [ # # ]: 0 : if (p == 2) c='*';
475 [ # # ]: 0 : if (p == 3) c='\n';
476 : 0 : BIO_write(cb->arg,&c,1);
477 : 0 : (void)BIO_flush(cb->arg);
478 : : #ifdef LINT
479 : : p=n;
480 : : #endif
481 : : #ifdef GENCB_TEST
482 : : if(stop_keygen_flag)
483 : : return 0;
484 : : #endif
485 : 0 : return 1;
486 : : }
487 : : #else /* !OPENSSL_NO_DSA */
488 : :
489 : : # if PEDANTIC
490 : : static void *dummy=&dummy;
491 : : # endif
492 : :
493 : : #endif
|