1295367Sdes/* apps/dsa.c */ 257429Smarkm/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 357429Smarkm * All rights reserved. 457429Smarkm * 557429Smarkm * This package is an SSL implementation written 657429Smarkm * by Eric Young (eay@cryptsoft.com). 757429Smarkm * The implementation was written so as to conform with Netscapes SSL. 857429Smarkm * 960576Skris * This library is free for commercial and non-commercial use as long as 1065674Skris * the following conditions are aheared to. The following conditions 1165674Skris * apply to all code found in this distribution, be it the RC4, RSA, 1265674Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1365674Skris * included with this distribution is covered by the same copyright terms 1465674Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1557429Smarkm * 1657429Smarkm * Copyright remains Eric Young's, and as such any Copyright notices in 1757429Smarkm * the code are not to be removed. 1857429Smarkm * If this package is used in a product, Eric Young should be given attribution 19295367Sdes * as the author of the parts of the library used. 20295367Sdes * This can be in the form of a textual message at program startup or 21162856Sdes * in documentation (online or textual) provided with the package. 22162856Sdes * 23162856Sdes * Redistribution and use in source and binary forms, with or without 2476262Sgreen * modification, are permitted provided that the following conditions 2576262Sgreen * are met: 26162856Sdes * 1. Redistributions of source code must retain the copyright 27162856Sdes * notice, this list of conditions and the following disclaimer. 28162856Sdes * 2. Redistributions in binary form must reproduce the above copyright 29162856Sdes * notice, this list of conditions and the following disclaimer in the 30162856Sdes * documentation and/or other materials provided with the distribution. 31162856Sdes * 3. All advertising materials mentioning features or use of this software 3257429Smarkm * must display the following acknowledgement: 3357429Smarkm * "This product includes cryptographic software written by 3476262Sgreen * Eric Young (eay@cryptsoft.com)" 3557429Smarkm * The word 'cryptographic' can be left out if the rouines from the library 3658585Skris * being used are not cryptographic related :-). 37162856Sdes * 4. If you include any Windows specific code (or a derivative thereof) from 3876262Sgreen * the apps directory (application code) you must include an acknowledgement: 3976262Sgreen * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40295367Sdes * 4157429Smarkm * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42162856Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43215116Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44162856Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4576262Sgreen * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46162856Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47162856Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48162856Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4998684Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5098684Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5157429Smarkm * SUCH DAMAGE. 52264377Sdes * 53264377Sdes * The licence and distribution terms for any publically available version or 5469591Sgreen * derivative of this code cannot be changed. i.e. this code cannot simply be 5569591Sgreen * copied and put under another distribution licence 5669591Sgreen * [including the GNU Public Licence.] 5757429Smarkm */ 5857429Smarkm 5957429Smarkm#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */ 6057429Smarkm#ifndef OPENSSL_NO_DSA 6176262Sgreen# include <stdio.h> 6257429Smarkm# include <stdlib.h> 6357429Smarkm# include <string.h> 6457429Smarkm# include <time.h> 6557429Smarkm# include "apps.h" 6657429Smarkm# include <openssl/bio.h> 6757429Smarkm# include <openssl/err.h> 6857429Smarkm# include <openssl/dsa.h> 69147005Sdes# include <openssl/evp.h> 7057429Smarkm# include <openssl/x509.h> 7157429Smarkm# include <openssl/pem.h> 7257429Smarkm# include <openssl/bn.h> 7398684Sdes 7498684Sdes# undef PROG 7598684Sdes# define PROG dsa_main 7698684Sdes 7798684Sdes/*- 7898684Sdes * -inform arg - input format - default PEM (one of DER, NET or PEM) 7998684Sdes * -outform arg - output format - default PEM 8098684Sdes * -in arg - input file - default stdin 8198684Sdes * -out arg - output file - default stdout 82164149Sdes * -des - encrypt output if PEM format with DES in cbc mode 83164149Sdes * -des3 - encrypt output if PEM format 8498684Sdes * -idea - encrypt output if PEM format 85164149Sdes * -aes128 - encrypt output if PEM format 86164149Sdes * -aes192 - encrypt output if PEM format 87164149Sdes * -aes256 - encrypt output if PEM format 8898684Sdes * -camellia128 - encrypt output if PEM format 8998684Sdes * -camellia192 - encrypt output if PEM format 9098684Sdes * -camellia256 - encrypt output if PEM format 9198684Sdes * -seed - encrypt output if PEM format 9298684Sdes * -text - print a text version 9398684Sdes * -modulus - print the DSA public key 9498684Sdes */ 9598684Sdes 9698684Sdesint MAIN(int, char **); 97264377Sdes 9898684Sdesint MAIN(int argc, char **argv) 9998684Sdes{ 10098684Sdes ENGINE *e = NULL; 10198684Sdes int ret = 1; 102264377Sdes DSA *dsa = NULL; 103264377Sdes int i, badops = 0; 10498684Sdes const EVP_CIPHER *enc = NULL; 10598684Sdes BIO *in = NULL, *out = NULL; 10698684Sdes int informat, outformat, text = 0, noout = 0; 10798684Sdes int pubin = 0, pubout = 0; 10898684Sdes char *infile, *outfile, *prog; 10998684Sdes# ifndef OPENSSL_NO_ENGINE 11098684Sdes char *engine; 111264377Sdes# endif 11298684Sdes char *passargin = NULL, *passargout = NULL; 11398684Sdes char *passin = NULL, *passout = NULL; 114264377Sdes int modulus = 0; 115264377Sdes 116264377Sdes int pvk_encr = 2; 117264377Sdes 118264377Sdes apps_startup(); 119264377Sdes 12098684Sdes if (bio_err == NULL) 12198684Sdes if ((bio_err = BIO_new(BIO_s_file())) != NULL) 122215116Sdes BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 12398684Sdes 12498684Sdes if (!load_config(bio_err, NULL)) 12598684Sdes goto end; 12698684Sdes 12798684Sdes# ifndef OPENSSL_NO_ENGINE 12898684Sdes engine = NULL; 12998684Sdes# endif 13057429Smarkm infile = NULL; 13157429Smarkm outfile = NULL; 13257429Smarkm informat = FORMAT_PEM; 13357429Smarkm outformat = FORMAT_PEM; 13457429Smarkm 13557429Smarkm prog = argv[0]; 13657429Smarkm argc--; 13798684Sdes argv++; 13857429Smarkm while (argc >= 1) { 13957429Smarkm if (strcmp(*argv, "-inform") == 0) { 14098684Sdes if (--argc < 1) 14198684Sdes goto bad; 14257429Smarkm informat = str2fmt(*(++argv)); 14392559Sdes } else if (strcmp(*argv, "-outform") == 0) { 14492559Sdes if (--argc < 1) 14557429Smarkm goto bad; 14698684Sdes outformat = str2fmt(*(++argv)); 14757429Smarkm } else if (strcmp(*argv, "-in") == 0) { 14857429Smarkm if (--argc < 1) 149295367Sdes goto bad; 150295367Sdes infile = *(++argv); 15157429Smarkm } else if (strcmp(*argv, "-out") == 0) { 15257429Smarkm if (--argc < 1) 15357429Smarkm goto bad; 15457429Smarkm outfile = *(++argv); 15557429Smarkm } else if (strcmp(*argv, "-passin") == 0) { 15657429Smarkm if (--argc < 1) 15757429Smarkm goto bad; 15857429Smarkm passargin = *(++argv); 15957429Smarkm } else if (strcmp(*argv, "-passout") == 0) { 16092559Sdes if (--argc < 1) 16157429Smarkm goto bad; 162162856Sdes passargout = *(++argv); 16392559Sdes } 16457429Smarkm# ifndef OPENSSL_NO_ENGINE 16598684Sdes else if (strcmp(*argv, "-engine") == 0) { 16657429Smarkm if (--argc < 1) 16798684Sdes goto bad; 16857429Smarkm engine = *(++argv); 16957429Smarkm } 170226046Sdes# endif 171226046Sdes else if (strcmp(*argv, "-pvk-strong") == 0) 172226046Sdes pvk_encr = 2; 17357429Smarkm else if (strcmp(*argv, "-pvk-weak") == 0) 174255767Sdes pvk_encr = 1; 175255767Sdes else if (strcmp(*argv, "-pvk-none") == 0) 17657429Smarkm pvk_encr = 0; 17776262Sgreen else if (strcmp(*argv, "-noout") == 0) 17892559Sdes noout = 1; 17957429Smarkm else if (strcmp(*argv, "-text") == 0) 18092559Sdes text = 1; 181226046Sdes else if (strcmp(*argv, "-modulus") == 0) 182226046Sdes modulus = 1; 18357429Smarkm else if (strcmp(*argv, "-pubin") == 0) 18457429Smarkm pubin = 1; 18557429Smarkm else if (strcmp(*argv, "-pubout") == 0) 18657429Smarkm pubout = 1; 18757429Smarkm else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { 18857429Smarkm BIO_printf(bio_err, "unknown option %s\n", *argv); 189226046Sdes badops = 1; 190147005Sdes break; 19157429Smarkm } 192137019Sdes argc--; 193149753Sdes argv++; 19457429Smarkm } 19557429Smarkm 19657429Smarkm if (badops) { 19757429Smarkm bad: 19857429Smarkm BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 19957429Smarkm BIO_printf(bio_err, "where options are\n"); 20057429Smarkm BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); 20157429Smarkm BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); 20257429Smarkm BIO_printf(bio_err, " -in arg input file\n"); 20357429Smarkm BIO_printf(bio_err, 20457429Smarkm " -passin arg input file pass phrase source\n"); 20557429Smarkm BIO_printf(bio_err, " -out arg output file\n"); 20657429Smarkm BIO_printf(bio_err, 20757429Smarkm " -passout arg output file pass phrase source\n"); 20857429Smarkm# ifndef OPENSSL_NO_ENGINE 209137019Sdes BIO_printf(bio_err, 21057429Smarkm " -engine e use engine e, possibly a hardware device.\n"); 21157429Smarkm# endif 21257429Smarkm BIO_printf(bio_err, 21357429Smarkm " -des encrypt PEM output with cbc des\n"); 21457429Smarkm BIO_printf(bio_err, 21557429Smarkm " -des3 encrypt PEM output with ede cbc des using 168 bit key\n"); 21657429Smarkm# ifndef OPENSSL_NO_IDEA 217137019Sdes BIO_printf(bio_err, 21857429Smarkm " -idea encrypt PEM output with cbc idea\n"); 21957429Smarkm# endif 22092559Sdes# ifndef OPENSSL_NO_AES 22192559Sdes BIO_printf(bio_err, " -aes128, -aes192, -aes256\n"); 22276262Sgreen BIO_printf(bio_err, 22357429Smarkm " encrypt PEM output with cbc aes\n"); 22457429Smarkm# endif 22557429Smarkm# ifndef OPENSSL_NO_CAMELLIA 22657429Smarkm BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n"); 227226046Sdes BIO_printf(bio_err, 228226046Sdes " encrypt PEM output with cbc camellia\n"); 229226046Sdes# endif 230226046Sdes# ifndef OPENSSL_NO_SEED 23192559Sdes BIO_printf(bio_err, 23257429Smarkm " -seed encrypt PEM output with cbc seed\n"); 23357429Smarkm# endif 23457429Smarkm BIO_printf(bio_err, " -text print the key in text\n"); 235149753Sdes BIO_printf(bio_err, " -noout don't print key out\n"); 236255767Sdes BIO_printf(bio_err, " -modulus print the DSA public value\n"); 237124211Sdes goto end; 23857429Smarkm } 23992559Sdes 24057429Smarkm ERR_load_crypto_strings(); 241295367Sdes 242295367Sdes# ifndef OPENSSL_NO_ENGINE 243295367Sdes e = setup_engine(bio_err, engine, 0); 244255767Sdes# endif 245255767Sdes 246255767Sdes if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 247255767Sdes BIO_printf(bio_err, "Error getting passwords\n"); 248221420Sdes goto end; 249221420Sdes } 250221420Sdes 251221420Sdes in = BIO_new(BIO_s_file()); 25257429Smarkm out = BIO_new(BIO_s_file()); 25376262Sgreen if ((in == NULL) || (out == NULL)) { 25476262Sgreen ERR_print_errors(bio_err); 25576262Sgreen goto end; 25676262Sgreen } 257137019Sdes 25876262Sgreen if (infile == NULL) 259215116Sdes BIO_set_fp(in, stdin, BIO_NOCLOSE); 260215116Sdes else { 26198684Sdes if (BIO_read_filename(in, infile) <= 0) { 26298684Sdes perror(infile); 26369591Sgreen goto end; 26457429Smarkm } 26557429Smarkm } 26657429Smarkm 26757429Smarkm BIO_printf(bio_err, "read DSA key\n"); 26857429Smarkm 26998684Sdes { 27098684Sdes EVP_PKEY *pkey; 27198684Sdes 27298684Sdes if (pubin) 27398684Sdes pkey = load_pubkey(bio_err, infile, informat, 1, 274226046Sdes passin, e, "Public Key"); 275226046Sdes else 27698684Sdes pkey = load_key(bio_err, infile, informat, 1, 27757429Smarkm passin, e, "Private Key"); 27898684Sdes 279226046Sdes if (pkey) { 280226046Sdes dsa = EVP_PKEY_get1_DSA(pkey); 281226046Sdes EVP_PKEY_free(pkey); 282226046Sdes } 283226046Sdes } 284226046Sdes if (dsa == NULL) { 285226046Sdes BIO_printf(bio_err, "unable to load Key\n"); 286226046Sdes ERR_print_errors(bio_err); 287226046Sdes goto end; 288226046Sdes } 289226046Sdes 290226046Sdes if (outfile == NULL) { 291226046Sdes BIO_set_fp(out, stdout, BIO_NOCLOSE); 292248619Sdes# ifdef OPENSSL_SYS_VMS 293248619Sdes { 294226046Sdes BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 295226046Sdes out = BIO_push(tmpbio, out); 296226046Sdes } 297255767Sdes# endif 298226046Sdes } else { 299226046Sdes if (BIO_write_filename(out, outfile) <= 0) { 300226046Sdes perror(outfile); 301226046Sdes goto end; 302226046Sdes } 303226046Sdes } 304226046Sdes 305226046Sdes if (text) 30698684Sdes if (!DSA_print(out, dsa, 0)) { 30798684Sdes perror(outfile); 30898684Sdes ERR_print_errors(bio_err); 30998684Sdes goto end; 31098684Sdes } 311126277Sdes 31298684Sdes if (modulus) { 31398684Sdes fprintf(stdout, "Public Key="); 314126277Sdes BN_print(out, dsa->pub_key); 31598684Sdes fprintf(stdout, "\n"); 31698684Sdes } 317126277Sdes 31898684Sdes if (noout) 31998684Sdes goto end; 32098684Sdes BIO_printf(bio_err, "writing DSA key\n"); 32169591Sgreen if (outformat == FORMAT_ASN1) { 32298684Sdes if (pubin || pubout) 32398684Sdes i = i2d_DSA_PUBKEY_bio(out, dsa); 32457429Smarkm else 32598684Sdes i = i2d_DSAPrivateKey_bio(out, dsa); 32698684Sdes } else if (outformat == FORMAT_PEM) { 32798684Sdes if (pubin || pubout) 32898684Sdes i = PEM_write_bio_DSA_PUBKEY(out, dsa); 32998684Sdes else 33098684Sdes i = PEM_write_bio_DSAPrivateKey(out, dsa, enc, 33198684Sdes NULL, 0, NULL, passout); 33298684Sdes# if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4) 33398684Sdes } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { 33498684Sdes EVP_PKEY *pk; 33598684Sdes pk = EVP_PKEY_new(); 33698684Sdes EVP_PKEY_set1_DSA(pk, dsa); 33798684Sdes if (outformat == FORMAT_PVK) 33898684Sdes i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); 33998684Sdes else if (pubin || pubout) 34098684Sdes i = i2b_PublicKey_bio(out, pk); 34198684Sdes else 34298684Sdes i = i2b_PrivateKey_bio(out, pk); 343255767Sdes EVP_PKEY_free(pk); 34498684Sdes# endif 34598684Sdes } else { 34698684Sdes BIO_printf(bio_err, "bad output format specified for outfile\n"); 34757429Smarkm goto end; 348295367Sdes } 349295367Sdes if (i <= 0) { 350 BIO_printf(bio_err, "unable to write private key\n"); 351 ERR_print_errors(bio_err); 352 } else 353 ret = 0; 354 end: 355 if (in != NULL) 356 BIO_free(in); 357 if (out != NULL) 358 BIO_free_all(out); 359 if (dsa != NULL) 360 DSA_free(dsa); 361 if (passin) 362 OPENSSL_free(passin); 363 if (passout) 364 OPENSSL_free(passout); 365 apps_shutdown(); 366 OPENSSL_EXIT(ret); 367} 368#else /* !OPENSSL_NO_DSA */ 369 370# if PEDANTIC 371static void *dummy = &dummy; 372# endif 373 374#endif 375