xref: /onnv-gate/usr/src/common/openssl/apps/dsaparam.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* apps/dsaparam.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
59*2139Sjp161948 #include <openssl/opensslconf.h>	/* for OPENSSL_NO_DSA */
60*2139Sjp161948 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
61*2139Sjp161948  * deprecated functions for openssl-internal code */
62*2139Sjp161948 #ifdef OPENSSL_NO_DEPRECATED
63*2139Sjp161948 #undef OPENSSL_NO_DEPRECATED
64*2139Sjp161948 #endif
65*2139Sjp161948 
660Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
670Sstevel@tonic-gate #include <assert.h>
680Sstevel@tonic-gate #include <stdio.h>
690Sstevel@tonic-gate #include <stdlib.h>
700Sstevel@tonic-gate #include <time.h>
710Sstevel@tonic-gate #include <string.h>
720Sstevel@tonic-gate #include "apps.h"
730Sstevel@tonic-gate #include <openssl/bio.h>
740Sstevel@tonic-gate #include <openssl/err.h>
750Sstevel@tonic-gate #include <openssl/bn.h>
760Sstevel@tonic-gate #include <openssl/dsa.h>
770Sstevel@tonic-gate #include <openssl/x509.h>
780Sstevel@tonic-gate #include <openssl/pem.h>
790Sstevel@tonic-gate 
800Sstevel@tonic-gate #undef PROG
810Sstevel@tonic-gate #define PROG	dsaparam_main
820Sstevel@tonic-gate 
830Sstevel@tonic-gate /* -inform arg	- input format - default PEM (DER or PEM)
840Sstevel@tonic-gate  * -outform arg - output format - default PEM
850Sstevel@tonic-gate  * -in arg	- input file - default stdin
860Sstevel@tonic-gate  * -out arg	- output file - default stdout
870Sstevel@tonic-gate  * -noout
880Sstevel@tonic-gate  * -text
890Sstevel@tonic-gate  * -C
900Sstevel@tonic-gate  * -noout
910Sstevel@tonic-gate  * -genkey
92*2139Sjp161948  *  #ifdef GENCB_TEST
93*2139Sjp161948  * -timebomb n  - interrupt keygen after <n> seconds
94*2139Sjp161948  *  #endif
950Sstevel@tonic-gate  */
960Sstevel@tonic-gate 
97*2139Sjp161948 #ifdef GENCB_TEST
98*2139Sjp161948 
99*2139Sjp161948 static int stop_keygen_flag = 0;
100*2139Sjp161948 
timebomb_sigalarm(int foo)101*2139Sjp161948 static void timebomb_sigalarm(int foo)
102*2139Sjp161948 	{
103*2139Sjp161948 	stop_keygen_flag = 1;
104*2139Sjp161948 	}
105*2139Sjp161948 
106*2139Sjp161948 #endif
107*2139Sjp161948 
108*2139Sjp161948 static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate int MAIN(int, char **);
1110Sstevel@tonic-gate 
MAIN(int argc,char ** argv)1120Sstevel@tonic-gate int MAIN(int argc, char **argv)
1130Sstevel@tonic-gate 	{
1140Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1150Sstevel@tonic-gate 	ENGINE *e = NULL;
1160Sstevel@tonic-gate #endif
1170Sstevel@tonic-gate 	DSA *dsa=NULL;
1180Sstevel@tonic-gate 	int i,badops=0,text=0;
1190Sstevel@tonic-gate 	BIO *in=NULL,*out=NULL;
1200Sstevel@tonic-gate 	int informat,outformat,noout=0,C=0,ret=1;
1210Sstevel@tonic-gate 	char *infile,*outfile,*prog,*inrand=NULL;
1220Sstevel@tonic-gate 	int numbits= -1,num,genkey=0;
1230Sstevel@tonic-gate 	int need_rand=0;
1240Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1250Sstevel@tonic-gate 	char *engine=NULL;
1260Sstevel@tonic-gate #endif
127*2139Sjp161948 #ifdef GENCB_TEST
128*2139Sjp161948 	int timebomb=0;
129*2139Sjp161948 #endif
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	apps_startup();
1320Sstevel@tonic-gate 
1330Sstevel@tonic-gate 	if (bio_err == NULL)
1340Sstevel@tonic-gate 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
1350Sstevel@tonic-gate 			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 	if (!load_config(bio_err, NULL))
1380Sstevel@tonic-gate 		goto end;
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 	infile=NULL;
1410Sstevel@tonic-gate 	outfile=NULL;
1420Sstevel@tonic-gate 	informat=FORMAT_PEM;
1430Sstevel@tonic-gate 	outformat=FORMAT_PEM;
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	prog=argv[0];
1460Sstevel@tonic-gate 	argc--;
1470Sstevel@tonic-gate 	argv++;
1480Sstevel@tonic-gate 	while (argc >= 1)
1490Sstevel@tonic-gate 		{
1500Sstevel@tonic-gate 		if 	(strcmp(*argv,"-inform") == 0)
1510Sstevel@tonic-gate 			{
1520Sstevel@tonic-gate 			if (--argc < 1) goto bad;
1530Sstevel@tonic-gate 			informat=str2fmt(*(++argv));
1540Sstevel@tonic-gate 			}
1550Sstevel@tonic-gate 		else if (strcmp(*argv,"-outform") == 0)
1560Sstevel@tonic-gate 			{
1570Sstevel@tonic-gate 			if (--argc < 1) goto bad;
1580Sstevel@tonic-gate 			outformat=str2fmt(*(++argv));
1590Sstevel@tonic-gate 			}
1600Sstevel@tonic-gate 		else if (strcmp(*argv,"-in") == 0)
1610Sstevel@tonic-gate 			{
1620Sstevel@tonic-gate 			if (--argc < 1) goto bad;
1630Sstevel@tonic-gate 			infile= *(++argv);
1640Sstevel@tonic-gate 			}
1650Sstevel@tonic-gate 		else if (strcmp(*argv,"-out") == 0)
1660Sstevel@tonic-gate 			{
1670Sstevel@tonic-gate 			if (--argc < 1) goto bad;
1680Sstevel@tonic-gate 			outfile= *(++argv);
1690Sstevel@tonic-gate 			}
1700Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
1710Sstevel@tonic-gate 		else if(strcmp(*argv, "-engine") == 0)
1720Sstevel@tonic-gate 			{
1730Sstevel@tonic-gate 			if (--argc < 1) goto bad;
1740Sstevel@tonic-gate 			engine = *(++argv);
1750Sstevel@tonic-gate 			}
1760Sstevel@tonic-gate #endif
177*2139Sjp161948 #ifdef GENCB_TEST
178*2139Sjp161948 		else if(strcmp(*argv, "-timebomb") == 0)
179*2139Sjp161948 			{
180*2139Sjp161948 			if (--argc < 1) goto bad;
181*2139Sjp161948 			timebomb = atoi(*(++argv));
182*2139Sjp161948 			}
183*2139Sjp161948 #endif
1840Sstevel@tonic-gate 		else if (strcmp(*argv,"-text") == 0)
1850Sstevel@tonic-gate 			text=1;
1860Sstevel@tonic-gate 		else if (strcmp(*argv,"-C") == 0)
1870Sstevel@tonic-gate 			C=1;
1880Sstevel@tonic-gate 		else if (strcmp(*argv,"-genkey") == 0)
1890Sstevel@tonic-gate 			{
1900Sstevel@tonic-gate 			genkey=1;
1910Sstevel@tonic-gate 			need_rand=1;
1920Sstevel@tonic-gate 			}
1930Sstevel@tonic-gate 		else if (strcmp(*argv,"-rand") == 0)
1940Sstevel@tonic-gate 			{
1950Sstevel@tonic-gate 			if (--argc < 1) goto bad;
1960Sstevel@tonic-gate 			inrand= *(++argv);
1970Sstevel@tonic-gate 			need_rand=1;
1980Sstevel@tonic-gate 			}
1990Sstevel@tonic-gate 		else if (strcmp(*argv,"-noout") == 0)
2000Sstevel@tonic-gate 			noout=1;
2010Sstevel@tonic-gate 		else if (sscanf(*argv,"%d",&num) == 1)
2020Sstevel@tonic-gate 			{
2030Sstevel@tonic-gate 			/* generate a key */
2040Sstevel@tonic-gate 			numbits=num;
2050Sstevel@tonic-gate 			need_rand=1;
2060Sstevel@tonic-gate 			}
2070Sstevel@tonic-gate 		else
2080Sstevel@tonic-gate 			{
2090Sstevel@tonic-gate 			BIO_printf(bio_err,"unknown option %s\n",*argv);
2100Sstevel@tonic-gate 			badops=1;
2110Sstevel@tonic-gate 			break;
2120Sstevel@tonic-gate 			}
2130Sstevel@tonic-gate 		argc--;
2140Sstevel@tonic-gate 		argv++;
2150Sstevel@tonic-gate 		}
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 	if (badops)
2180Sstevel@tonic-gate 		{
2190Sstevel@tonic-gate bad:
2200Sstevel@tonic-gate 		BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog);
2210Sstevel@tonic-gate 		BIO_printf(bio_err,"where options are\n");
2220Sstevel@tonic-gate 		BIO_printf(bio_err," -inform arg   input format - DER or PEM\n");
2230Sstevel@tonic-gate 		BIO_printf(bio_err," -outform arg  output format - DER or PEM\n");
2240Sstevel@tonic-gate 		BIO_printf(bio_err," -in arg       input file\n");
2250Sstevel@tonic-gate 		BIO_printf(bio_err," -out arg      output file\n");
2260Sstevel@tonic-gate 		BIO_printf(bio_err," -text         print as text\n");
2270Sstevel@tonic-gate 		BIO_printf(bio_err," -C            Output C code\n");
2280Sstevel@tonic-gate 		BIO_printf(bio_err," -noout        no output\n");
2290Sstevel@tonic-gate 		BIO_printf(bio_err," -genkey       generate a DSA key\n");
2300Sstevel@tonic-gate 		BIO_printf(bio_err," -rand         files to use for random number input\n");
2310Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2320Sstevel@tonic-gate 		BIO_printf(bio_err," -engine e     use engine e, possibly a hardware device.\n");
2330Sstevel@tonic-gate #endif
234*2139Sjp161948 #ifdef GENCB_TEST
235*2139Sjp161948 		BIO_printf(bio_err," -timebomb n   interrupt keygen after <n> seconds\n");
236*2139Sjp161948 #endif
2370Sstevel@tonic-gate 		BIO_printf(bio_err," number        number of bits to use for generating private key\n");
2380Sstevel@tonic-gate 		goto end;
2390Sstevel@tonic-gate 		}
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate 	ERR_load_crypto_strings();
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 	in=BIO_new(BIO_s_file());
2440Sstevel@tonic-gate 	out=BIO_new(BIO_s_file());
2450Sstevel@tonic-gate 	if ((in == NULL) || (out == NULL))
2460Sstevel@tonic-gate 		{
2470Sstevel@tonic-gate 		ERR_print_errors(bio_err);
2480Sstevel@tonic-gate 		goto end;
2490Sstevel@tonic-gate 		}
2500Sstevel@tonic-gate 
2510Sstevel@tonic-gate 	if (infile == NULL)
2520Sstevel@tonic-gate 		BIO_set_fp(in,stdin,BIO_NOCLOSE);
2530Sstevel@tonic-gate 	else
2540Sstevel@tonic-gate 		{
2550Sstevel@tonic-gate 		if (BIO_read_filename(in,infile) <= 0)
2560Sstevel@tonic-gate 			{
2570Sstevel@tonic-gate 			perror(infile);
2580Sstevel@tonic-gate 			goto end;
2590Sstevel@tonic-gate 			}
2600Sstevel@tonic-gate 		}
2610Sstevel@tonic-gate 	if (outfile == NULL)
2620Sstevel@tonic-gate 		{
2630Sstevel@tonic-gate 		BIO_set_fp(out,stdout,BIO_NOCLOSE);
2640Sstevel@tonic-gate #ifdef OPENSSL_SYS_VMS
2650Sstevel@tonic-gate 		{
2660Sstevel@tonic-gate 		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
2670Sstevel@tonic-gate 		out = BIO_push(tmpbio, out);
2680Sstevel@tonic-gate 		}
2690Sstevel@tonic-gate #endif
2700Sstevel@tonic-gate 		}
2710Sstevel@tonic-gate 	else
2720Sstevel@tonic-gate 		{
2730Sstevel@tonic-gate 		if (BIO_write_filename(out,outfile) <= 0)
2740Sstevel@tonic-gate 			{
2750Sstevel@tonic-gate 			perror(outfile);
2760Sstevel@tonic-gate 			goto end;
2770Sstevel@tonic-gate 			}
2780Sstevel@tonic-gate 		}
2790Sstevel@tonic-gate 
2800Sstevel@tonic-gate #ifndef OPENSSL_NO_ENGINE
2810Sstevel@tonic-gate         e = setup_engine(bio_err, engine, 0);
2820Sstevel@tonic-gate #endif
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	if (need_rand)
2850Sstevel@tonic-gate 		{
2860Sstevel@tonic-gate 		app_RAND_load_file(NULL, bio_err, (inrand != NULL));
2870Sstevel@tonic-gate 		if (inrand != NULL)
2880Sstevel@tonic-gate 			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
2890Sstevel@tonic-gate 				app_RAND_load_files(inrand));
2900Sstevel@tonic-gate 		}
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate 	if (numbits > 0)
2930Sstevel@tonic-gate 		{
294*2139Sjp161948 		BN_GENCB cb;
295*2139Sjp161948 		BN_GENCB_set(&cb, dsa_cb, bio_err);
2960Sstevel@tonic-gate 		assert(need_rand);
297*2139Sjp161948 		dsa = DSA_new();
298*2139Sjp161948 		if(!dsa)
299*2139Sjp161948 			{
300*2139Sjp161948 			BIO_printf(bio_err,"Error allocating DSA object\n");
301*2139Sjp161948 			goto end;
302*2139Sjp161948 			}
3030Sstevel@tonic-gate 		BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
3040Sstevel@tonic-gate 	        BIO_printf(bio_err,"This could take some time\n");
305*2139Sjp161948 #ifdef GENCB_TEST
306*2139Sjp161948 		if(timebomb > 0)
307*2139Sjp161948 	{
308*2139Sjp161948 		struct sigaction act;
309*2139Sjp161948 		act.sa_handler = timebomb_sigalarm;
310*2139Sjp161948 		act.sa_flags = 0;
311*2139Sjp161948 		BIO_printf(bio_err,"(though I'll stop it if not done within %d secs)\n",
312*2139Sjp161948 				timebomb);
313*2139Sjp161948 		if(sigaction(SIGALRM, &act, NULL) != 0)
314*2139Sjp161948 			{
315*2139Sjp161948 			BIO_printf(bio_err,"Error, couldn't set SIGALRM handler\n");
316*2139Sjp161948 			goto end;
317*2139Sjp161948 			}
318*2139Sjp161948 		alarm(timebomb);
319*2139Sjp161948 	}
320*2139Sjp161948 #endif
321*2139Sjp161948 	        if(!DSA_generate_parameters_ex(dsa,num,NULL,0,NULL,NULL, &cb))
322*2139Sjp161948 			{
323*2139Sjp161948 #ifdef GENCB_TEST
324*2139Sjp161948 			if(stop_keygen_flag)
325*2139Sjp161948 				{
326*2139Sjp161948 				BIO_printf(bio_err,"DSA key generation time-stopped\n");
327*2139Sjp161948 				/* This is an asked-for behaviour! */
328*2139Sjp161948 				ret = 0;
329*2139Sjp161948 				goto end;
330*2139Sjp161948 				}
331*2139Sjp161948 #endif
332*2139Sjp161948 			BIO_printf(bio_err,"Error, DSA key generation failed\n");
333*2139Sjp161948 			goto end;
334*2139Sjp161948 			}
3350Sstevel@tonic-gate 		}
3360Sstevel@tonic-gate 	else if	(informat == FORMAT_ASN1)
3370Sstevel@tonic-gate 		dsa=d2i_DSAparams_bio(in,NULL);
3380Sstevel@tonic-gate 	else if (informat == FORMAT_PEM)
3390Sstevel@tonic-gate 		dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
3400Sstevel@tonic-gate 	else
3410Sstevel@tonic-gate 		{
3420Sstevel@tonic-gate 		BIO_printf(bio_err,"bad input format specified\n");
3430Sstevel@tonic-gate 		goto end;
3440Sstevel@tonic-gate 		}
3450Sstevel@tonic-gate 	if (dsa == NULL)
3460Sstevel@tonic-gate 		{
3470Sstevel@tonic-gate 		BIO_printf(bio_err,"unable to load DSA parameters\n");
3480Sstevel@tonic-gate 		ERR_print_errors(bio_err);
3490Sstevel@tonic-gate 		goto end;
3500Sstevel@tonic-gate 		}
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	if (text)
3530Sstevel@tonic-gate 		{
3540Sstevel@tonic-gate 		DSAparams_print(out,dsa);
3550Sstevel@tonic-gate 		}
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	if (C)
3580Sstevel@tonic-gate 		{
3590Sstevel@tonic-gate 		unsigned char *data;
3600Sstevel@tonic-gate 		int l,len,bits_p,bits_q,bits_g;
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 		len=BN_num_bytes(dsa->p);
3630Sstevel@tonic-gate 		bits_p=BN_num_bits(dsa->p);
3640Sstevel@tonic-gate 		bits_q=BN_num_bits(dsa->q);
3650Sstevel@tonic-gate 		bits_g=BN_num_bits(dsa->g);
3660Sstevel@tonic-gate 		data=(unsigned char *)OPENSSL_malloc(len+20);
3670Sstevel@tonic-gate 		if (data == NULL)
3680Sstevel@tonic-gate 			{
3690Sstevel@tonic-gate 			perror("OPENSSL_malloc");
3700Sstevel@tonic-gate 			goto end;
3710Sstevel@tonic-gate 			}
3720Sstevel@tonic-gate 		l=BN_bn2bin(dsa->p,data);
3730Sstevel@tonic-gate 		printf("static unsigned char dsa%d_p[]={",bits_p);
3740Sstevel@tonic-gate 		for (i=0; i<l; i++)
3750Sstevel@tonic-gate 			{
3760Sstevel@tonic-gate 			if ((i%12) == 0) printf("\n\t");
3770Sstevel@tonic-gate 			printf("0x%02X,",data[i]);
3780Sstevel@tonic-gate 			}
3790Sstevel@tonic-gate 		printf("\n\t};\n");
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate 		l=BN_bn2bin(dsa->q,data);
3820Sstevel@tonic-gate 		printf("static unsigned char dsa%d_q[]={",bits_p);
3830Sstevel@tonic-gate 		for (i=0; i<l; i++)
3840Sstevel@tonic-gate 			{
3850Sstevel@tonic-gate 			if ((i%12) == 0) printf("\n\t");
3860Sstevel@tonic-gate 			printf("0x%02X,",data[i]);
3870Sstevel@tonic-gate 			}
3880Sstevel@tonic-gate 		printf("\n\t};\n");
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 		l=BN_bn2bin(dsa->g,data);
3910Sstevel@tonic-gate 		printf("static unsigned char dsa%d_g[]={",bits_p);
3920Sstevel@tonic-gate 		for (i=0; i<l; i++)
3930Sstevel@tonic-gate 			{
3940Sstevel@tonic-gate 			if ((i%12) == 0) printf("\n\t");
3950Sstevel@tonic-gate 			printf("0x%02X,",data[i]);
3960Sstevel@tonic-gate 			}
3970Sstevel@tonic-gate 		printf("\n\t};\n\n");
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 		printf("DSA *get_dsa%d()\n\t{\n",bits_p);
4000Sstevel@tonic-gate 		printf("\tDSA *dsa;\n\n");
4010Sstevel@tonic-gate 		printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n");
4020Sstevel@tonic-gate 		printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n",
4030Sstevel@tonic-gate 			bits_p,bits_p);
4040Sstevel@tonic-gate 		printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n",
4050Sstevel@tonic-gate 			bits_p,bits_p);
4060Sstevel@tonic-gate 		printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n",
4070Sstevel@tonic-gate 			bits_p,bits_p);
4080Sstevel@tonic-gate 		printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n");
4090Sstevel@tonic-gate 		printf("\t\t{ DSA_free(dsa); return(NULL); }\n");
4100Sstevel@tonic-gate 		printf("\treturn(dsa);\n\t}\n");
4110Sstevel@tonic-gate 		}
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate 	if (!noout)
4150Sstevel@tonic-gate 		{
4160Sstevel@tonic-gate 		if 	(outformat == FORMAT_ASN1)
4170Sstevel@tonic-gate 			i=i2d_DSAparams_bio(out,dsa);
4180Sstevel@tonic-gate 		else if (outformat == FORMAT_PEM)
4190Sstevel@tonic-gate 			i=PEM_write_bio_DSAparams(out,dsa);
4200Sstevel@tonic-gate 		else	{
4210Sstevel@tonic-gate 			BIO_printf(bio_err,"bad output format specified for outfile\n");
4220Sstevel@tonic-gate 			goto end;
4230Sstevel@tonic-gate 			}
4240Sstevel@tonic-gate 		if (!i)
4250Sstevel@tonic-gate 			{
4260Sstevel@tonic-gate 			BIO_printf(bio_err,"unable to write DSA parameters\n");
4270Sstevel@tonic-gate 			ERR_print_errors(bio_err);
4280Sstevel@tonic-gate 			goto end;
4290Sstevel@tonic-gate 			}
4300Sstevel@tonic-gate 		}
4310Sstevel@tonic-gate 	if (genkey)
4320Sstevel@tonic-gate 		{
4330Sstevel@tonic-gate 		DSA *dsakey;
4340Sstevel@tonic-gate 
4350Sstevel@tonic-gate 		assert(need_rand);
4360Sstevel@tonic-gate 		if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
4370Sstevel@tonic-gate 		if (!DSA_generate_key(dsakey)) goto end;
4380Sstevel@tonic-gate 		if 	(outformat == FORMAT_ASN1)
4390Sstevel@tonic-gate 			i=i2d_DSAPrivateKey_bio(out,dsakey);
4400Sstevel@tonic-gate 		else if (outformat == FORMAT_PEM)
4410Sstevel@tonic-gate 			i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL);
4420Sstevel@tonic-gate 		else	{
4430Sstevel@tonic-gate 			BIO_printf(bio_err,"bad output format specified for outfile\n");
4440Sstevel@tonic-gate 			goto end;
4450Sstevel@tonic-gate 			}
4460Sstevel@tonic-gate 		DSA_free(dsakey);
4470Sstevel@tonic-gate 		}
4480Sstevel@tonic-gate 	if (need_rand)
4490Sstevel@tonic-gate 		app_RAND_write_file(NULL, bio_err);
4500Sstevel@tonic-gate 	ret=0;
4510Sstevel@tonic-gate end:
4520Sstevel@tonic-gate 	if (in != NULL) BIO_free(in);
4530Sstevel@tonic-gate 	if (out != NULL) BIO_free_all(out);
4540Sstevel@tonic-gate 	if (dsa != NULL) DSA_free(dsa);
4550Sstevel@tonic-gate 	apps_shutdown();
4560Sstevel@tonic-gate 	OPENSSL_EXIT(ret);
4570Sstevel@tonic-gate 	}
4580Sstevel@tonic-gate 
dsa_cb(int p,int n,BN_GENCB * cb)459*2139Sjp161948 static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
4600Sstevel@tonic-gate 	{
4610Sstevel@tonic-gate 	char c='*';
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	if (p == 0) c='.';
4640Sstevel@tonic-gate 	if (p == 1) c='+';
4650Sstevel@tonic-gate 	if (p == 2) c='*';
4660Sstevel@tonic-gate 	if (p == 3) c='\n';
467*2139Sjp161948 	BIO_write(cb->arg,&c,1);
468*2139Sjp161948 	(void)BIO_flush(cb->arg);
4690Sstevel@tonic-gate #ifdef LINT
4700Sstevel@tonic-gate 	p=n;
4710Sstevel@tonic-gate #endif
472*2139Sjp161948 #ifdef GENCB_TEST
473*2139Sjp161948 	if(stop_keygen_flag)
474*2139Sjp161948 		return 0;
475*2139Sjp161948 #endif
476*2139Sjp161948 	return 1;
4770Sstevel@tonic-gate 	}
4780Sstevel@tonic-gate #endif
479