Home | History | Annotate | Download | only in apps
      1 /* apps/dsa.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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/evp.h>
     69 #include <openssl/x509.h>
     70 #include <openssl/pem.h>
     71 #include <openssl/bn.h>
     72 #include <openssl/dsa.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 
     95 int MAIN(int, char **);
     96 
     97 int 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 		{
    196 bad:
    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;
    324 end:
    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