int MAIN(int argc, char **argv)
	{
	ENGINE *e = NULL;
	DSA *dsa=NULL;
	int ret=1;
	char *outfile=NULL;
	char *inrand=NULL,*dsaparams=NULL;
	char *passargout = NULL, *passout = NULL;
	BIO *out=NULL,*in=NULL;
	EVP_CIPHER *enc=NULL;
	char *engine=NULL;

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	argv++;
	argc--;
	for (;;)
		{
		if (argc <= 0) break;
		if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-passout") == 0)
			{
			if (--argc < 1) goto bad;
			passargout= *(++argv);
			}
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			}
		else if (strcmp(*argv,"-") == 0)
			goto bad;
#ifndef NO_DES
		else if (strcmp(*argv,"-des") == 0)
			enc=EVP_des_cbc();
		else if (strcmp(*argv,"-des3") == 0)
			enc=EVP_des_ede3_cbc();
#endif
#ifndef NO_IDEA
		else if (strcmp(*argv,"-idea") == 0)
			enc=EVP_idea_cbc();
#endif
		else if (**argv != '-' && dsaparams == NULL)
			{
			dsaparams = *argv;
			}
		else
			goto bad;
		argv++;
		argc--;
		}

	if (dsaparams == NULL)
		{
bad:
		BIO_printf(bio_err,"usage: gendsa [args] dsaparam-file\n");
		BIO_printf(bio_err," -out file - output the key to 'file'\n");
#ifndef NO_DES
		BIO_printf(bio_err," -des      - encrypt the generated key with DES in cbc mode\n");
		BIO_printf(bio_err," -des3     - encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
#endif
#ifndef NO_IDEA
		BIO_printf(bio_err," -idea     - encrypt the generated key with IDEA in cbc mode\n");
#endif
		BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
		BIO_printf(bio_err,"           - load the file (or the files in the directory) into\n");
		BIO_printf(bio_err,"             the random number generator\n");
		BIO_printf(bio_err," dsaparam-file\n");
		BIO_printf(bio_err,"           - a DSA parameter file as generated by the dsaparam command\n");
		goto end;
		}

	if (engine != NULL)
		{
		if((e = ENGINE_by_id(engine)) == NULL)
			{
			BIO_printf(bio_err,"invalid engine \"%s\"\n",
				engine);
			goto end;
			}
		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
			{
			BIO_printf(bio_err,"can't use that engine\n");
			goto end;
			}
		BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
		/* Free our "structural" reference. */
		ENGINE_free(e);
		}

	if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}


	in=BIO_new(BIO_s_file());
	if (!(BIO_read_filename(in,dsaparams)))
		{
		perror(dsaparams);
		goto end;
		}

	if ((dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
		{
		BIO_printf(bio_err,"unable to load DSA parameter file\n");
		goto end;
		}
	BIO_free(in);
	in = NULL;
		
	out=BIO_new(BIO_s_file());
	if (out == NULL) goto end;

	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outfile) <= 0)
			{
			perror(outfile);
			goto end;
			}
		}

	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
		{
		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
		}
	if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));

	BIO_printf(bio_err,"Generating DSA key, %d bits\n",
							BN_num_bits(dsa->p));
	if (!DSA_generate_key(dsa)) goto end;

	app_RAND_write_file(NULL, bio_err);

	if (!PEM_write_bio_DSAPrivateKey(out,dsa,enc,NULL,0,NULL, passout))
		goto end;
	ret=0;
end:
	if (ret != 0)
		ERR_print_errors(bio_err);
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (dsa != NULL) DSA_free(dsa);
	if(passout) OPENSSL_free(passout);
	EXIT(ret);
	}