dsa.c revision 194206
1262456Sbr/* apps/dsa.c */
2262456Sbr/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3262456Sbr * All rights reserved.
4262456Sbr *
5262456Sbr * This package is an SSL implementation written
6262456Sbr * by Eric Young (eay@cryptsoft.com).
7262456Sbr * The implementation was written so as to conform with Netscapes SSL.
8262456Sbr *
9262456Sbr * This library is free for commercial and non-commercial use as long as
10262456Sbr * the following conditions are aheared to.  The following conditions
11262456Sbr * apply to all code found in this distribution, be it the RC4, RSA,
12262456Sbr * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13262456Sbr * included with this distribution is covered by the same copyright terms
14262456Sbr * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15262456Sbr *
16262456Sbr * Copyright remains Eric Young's, and as such any Copyright notices in
17262456Sbr * the code are not to be removed.
18262456Sbr * If this package is used in a product, Eric Young should be given attribution
19262456Sbr * as the author of the parts of the library used.
20266383Sian * This can be in the form of a textual message at program startup or
21266383Sian * in documentation (online or textual) provided with the package.
22266383Sian *
23262456Sbr * Redistribution and use in source and binary forms, with or without
24262456Sbr * modification, are permitted provided that the following conditions
25262456Sbr * are met:
26266331Sian * 1. Redistributions of source code must retain the copyright
27266331Sian *    notice, this list of conditions and the following disclaimer.
28262456Sbr * 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#ifndef OPENSSL_NO_DSA
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <time.h>
65#include "apps.h"
66#include <openssl/bio.h>
67#include <openssl/err.h>
68#include <openssl/dsa.h>
69#include <openssl/evp.h>
70#include <openssl/x509.h>
71#include <openssl/pem.h>
72#include <openssl/bn.h>
73
74#undef PROG
75#define PROG	dsa_main
76
77/* -inform arg	- input format - default PEM (one of DER, NET or PEM)
78 * -outform arg - output format - default PEM
79 * -in arg	- input file - default stdin
80 * -out arg	- output file - default stdout
81 * -des		- encrypt output if PEM format with DES in cbc mode
82 * -des3	- encrypt output if PEM format
83 * -idea	- encrypt output if PEM format
84 * -aes128	- encrypt output if PEM format
85 * -aes192	- encrypt output if PEM format
86 * -aes256	- encrypt output if PEM format
87 * -camellia128 - encrypt output if PEM format
88 * -camellia192 - encrypt output if PEM format
89 * -camellia256 - encrypt output if PEM format
90 * -seed        - encrypt output if PEM format
91 * -text	- print a text version
92 * -modulus	- print the DSA public key
93 */
94
95int MAIN(int, char **);
96
97int MAIN(int argc, char **argv)
98	{
99	ENGINE *e = NULL;
100	int ret=1;
101	DSA *dsa=NULL;
102	int i,badops=0;
103	const EVP_CIPHER *enc=NULL;
104	BIO *in=NULL,*out=NULL;
105	int informat,outformat,text=0,noout=0;
106	int pubin = 0, pubout = 0;
107	char *infile,*outfile,*prog;
108#ifndef OPENSSL_NO_ENGINE
109	char *engine;
110#endif
111	char *passargin = NULL, *passargout = NULL;
112	char *passin = NULL, *passout = NULL;
113	int modulus=0;
114
115	apps_startup();
116
117	if (bio_err == NULL)
118		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
119			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
120
121	if (!load_config(bio_err, NULL))
122		goto end;
123
124#ifndef OPENSSL_NO_ENGINE
125	engine=NULL;
126#endif
127	infile=NULL;
128	outfile=NULL;
129	informat=FORMAT_PEM;
130	outformat=FORMAT_PEM;
131
132	prog=argv[0];
133	argc--;
134	argv++;
135	while (argc >= 1)
136		{
137		if 	(strcmp(*argv,"-inform") == 0)
138			{
139			if (--argc < 1) goto bad;
140			informat=str2fmt(*(++argv));
141			}
142		else if (strcmp(*argv,"-outform") == 0)
143			{
144			if (--argc < 1) goto bad;
145			outformat=str2fmt(*(++argv));
146			}
147		else if (strcmp(*argv,"-in") == 0)
148			{
149			if (--argc < 1) goto bad;
150			infile= *(++argv);
151			}
152		else if (strcmp(*argv,"-out") == 0)
153			{
154			if (--argc < 1) goto bad;
155			outfile= *(++argv);
156			}
157		else if (strcmp(*argv,"-passin") == 0)
158			{
159			if (--argc < 1) goto bad;
160			passargin= *(++argv);
161			}
162		else if (strcmp(*argv,"-passout") == 0)
163			{
164			if (--argc < 1) goto bad;
165			passargout= *(++argv);
166			}
167#ifndef OPENSSL_NO_ENGINE
168		else if (strcmp(*argv,"-engine") == 0)
169			{
170			if (--argc < 1) goto bad;
171			engine= *(++argv);
172			}
173#endif
174		else if (strcmp(*argv,"-noout") == 0)
175			noout=1;
176		else if (strcmp(*argv,"-text") == 0)
177			text=1;
178		else if (strcmp(*argv,"-modulus") == 0)
179			modulus=1;
180		else if (strcmp(*argv,"-pubin") == 0)
181			pubin=1;
182		else if (strcmp(*argv,"-pubout") == 0)
183			pubout=1;
184		else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
185			{
186			BIO_printf(bio_err,"unknown option %s\n",*argv);
187			badops=1;
188			break;
189			}
190		argc--;
191		argv++;
192		}
193
194	if (badops)
195		{
196bad:
197		BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
198		BIO_printf(bio_err,"where options are\n");
199		BIO_printf(bio_err," -inform arg     input format - DER or PEM\n");
200		BIO_printf(bio_err," -outform arg    output format - DER or PEM\n");
201		BIO_printf(bio_err," -in arg         input file\n");
202		BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
203		BIO_printf(bio_err," -out arg        output file\n");
204		BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
205#ifndef OPENSSL_NO_ENGINE
206		BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
207#endif
208		BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
209		BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
210#ifndef OPENSSL_NO_IDEA
211		BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
212#endif
213#ifndef OPENSSL_NO_AES
214		BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
215		BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
216#endif
217#ifndef OPENSSL_NO_CAMELLIA
218		BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n");
219		BIO_printf(bio_err,"                 encrypt PEM output with cbc camellia\n");
220#endif
221#ifndef OPENSSL_NO_SEED
222		BIO_printf(bio_err," -seed           encrypt PEM output with cbc seed\n");
223#endif
224		BIO_printf(bio_err," -text           print the key in text\n");
225		BIO_printf(bio_err," -noout          don't print key out\n");
226		BIO_printf(bio_err," -modulus        print the DSA public value\n");
227		goto end;
228		}
229
230	ERR_load_crypto_strings();
231
232#ifndef OPENSSL_NO_ENGINE
233        e = setup_engine(bio_err, engine, 0);
234#endif
235
236	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
237		BIO_printf(bio_err, "Error getting passwords\n");
238		goto end;
239	}
240
241	out=BIO_new(BIO_s_file());
242	if (out == NULL)
243		{
244		ERR_print_errors(bio_err);
245		goto end;
246		}
247
248	BIO_printf(bio_err,"read DSA key\n");
249	{
250		EVP_PKEY	*pkey;
251		if (pubin)
252			pkey = load_pubkey(bio_err, infile, informat, 1,
253				passin, e, "Public Key");
254		else
255			pkey = load_key(bio_err, infile, informat, 1,
256				passin, e, "Private Key");
257
258		if (pkey != NULL)
259		dsa = pkey == NULL ? NULL : EVP_PKEY_get1_DSA(pkey);
260		EVP_PKEY_free(pkey);
261	}
262	if (dsa == NULL)
263		{
264		BIO_printf(bio_err,"unable to load Key\n");
265		ERR_print_errors(bio_err);
266		goto end;
267		}
268
269	if (outfile == NULL)
270		{
271		BIO_set_fp(out,stdout,BIO_NOCLOSE);
272#ifdef OPENSSL_SYS_VMS
273		{
274		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
275		out = BIO_push(tmpbio, out);
276		}
277#endif
278		}
279	else
280		{
281		if (BIO_write_filename(out,outfile) <= 0)
282			{
283			perror(outfile);
284			goto end;
285			}
286		}
287
288	if (text)
289		if (!DSA_print(out,dsa,0))
290			{
291			perror(outfile);
292			ERR_print_errors(bio_err);
293			goto end;
294			}
295
296	if (modulus)
297		{
298		fprintf(stdout,"Public Key=");
299		BN_print(out,dsa->pub_key);
300		fprintf(stdout,"\n");
301		}
302
303	if (noout) goto end;
304	BIO_printf(bio_err,"writing DSA key\n");
305	if 	(outformat == FORMAT_ASN1) {
306		if(pubin || pubout) i=i2d_DSA_PUBKEY_bio(out,dsa);
307		else i=i2d_DSAPrivateKey_bio(out,dsa);
308	} else if (outformat == FORMAT_PEM) {
309		if(pubin || pubout)
310			i=PEM_write_bio_DSA_PUBKEY(out,dsa);
311		else i=PEM_write_bio_DSAPrivateKey(out,dsa,enc,
312							NULL,0,NULL, passout);
313	} else {
314		BIO_printf(bio_err,"bad output format specified for outfile\n");
315		goto end;
316		}
317	if (!i)
318		{
319		BIO_printf(bio_err,"unable to write private key\n");
320		ERR_print_errors(bio_err);
321		}
322	else
323		ret=0;
324end:
325	if(in != NULL) BIO_free(in);
326	if(out != NULL) BIO_free_all(out);
327	if(dsa != NULL) DSA_free(dsa);
328	if(passin) OPENSSL_free(passin);
329	if(passout) OPENSSL_free(passout);
330	apps_shutdown();
331	OPENSSL_EXIT(ret);
332	}
333#endif
334