Annotation of src/usr.bin/openssl/dsa.c, Revision 1.1
1.1 ! jsing 1: /* $OpenBSD: dsa.c,v 1.29 2014/07/25 06:05:31 doug Exp $ */
! 2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
! 3: * All rights reserved.
! 4: *
! 5: * This package is an SSL implementation written
! 6: * by Eric Young (eay@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@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@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:
! 61:
! 62: #include <stdio.h>
! 63: #include <stdlib.h>
! 64: #include <time.h>
! 65: #include <string.h>
! 66:
! 67: #include "apps.h"
! 68:
! 69: #include <openssl/bio.h>
! 70: #include <openssl/bn.h>
! 71: #include <openssl/dsa.h>
! 72: #include <openssl/err.h>
! 73: #include <openssl/evp.h>
! 74: #include <openssl/pem.h>
! 75: #include <openssl/x509.h>
! 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 dsa_main(int, char **);
! 96:
! 97: int
! 98: dsa_main(int argc, char **argv)
! 99: {
! 100: ENGINE *e = NULL;
! 101: int ret = 1;
! 102: DSA *dsa = NULL;
! 103: int i, badops = 0;
! 104: const EVP_CIPHER *enc = NULL;
! 105: BIO *in = NULL, *out = NULL;
! 106: int informat, outformat, text = 0, noout = 0;
! 107: int pubin = 0, pubout = 0;
! 108: char *infile, *outfile, *prog;
! 109: #ifndef OPENSSL_NO_ENGINE
! 110: char *engine;
! 111: #endif
! 112: char *passargin = NULL, *passargout = NULL;
! 113: char *passin = NULL, *passout = NULL;
! 114: int modulus = 0;
! 115:
! 116: int pvk_encr = 2;
! 117:
! 118: #ifndef OPENSSL_NO_ENGINE
! 119: engine = NULL;
! 120: #endif
! 121: infile = NULL;
! 122: outfile = NULL;
! 123: informat = FORMAT_PEM;
! 124: outformat = FORMAT_PEM;
! 125:
! 126: prog = argv[0];
! 127: argc--;
! 128: argv++;
! 129: while (argc >= 1) {
! 130: if (strcmp(*argv, "-inform") == 0) {
! 131: if (--argc < 1)
! 132: goto bad;
! 133: informat = str2fmt(*(++argv));
! 134: } else if (strcmp(*argv, "-outform") == 0) {
! 135: if (--argc < 1)
! 136: goto bad;
! 137: outformat = str2fmt(*(++argv));
! 138: } else if (strcmp(*argv, "-in") == 0) {
! 139: if (--argc < 1)
! 140: goto bad;
! 141: infile = *(++argv);
! 142: } else if (strcmp(*argv, "-out") == 0) {
! 143: if (--argc < 1)
! 144: goto bad;
! 145: outfile = *(++argv);
! 146: } else if (strcmp(*argv, "-passin") == 0) {
! 147: if (--argc < 1)
! 148: goto bad;
! 149: passargin = *(++argv);
! 150: } else if (strcmp(*argv, "-passout") == 0) {
! 151: if (--argc < 1)
! 152: goto bad;
! 153: passargout = *(++argv);
! 154: }
! 155: #ifndef OPENSSL_NO_ENGINE
! 156: else if (strcmp(*argv, "-engine") == 0) {
! 157: if (--argc < 1)
! 158: goto bad;
! 159: engine = *(++argv);
! 160: }
! 161: #endif
! 162: else if (strcmp(*argv, "-pvk-strong") == 0)
! 163: pvk_encr = 2;
! 164: else if (strcmp(*argv, "-pvk-weak") == 0)
! 165: pvk_encr = 1;
! 166: else if (strcmp(*argv, "-pvk-none") == 0)
! 167: pvk_encr = 0;
! 168: else if (strcmp(*argv, "-noout") == 0)
! 169: noout = 1;
! 170: else if (strcmp(*argv, "-text") == 0)
! 171: text = 1;
! 172: else if (strcmp(*argv, "-modulus") == 0)
! 173: modulus = 1;
! 174: else if (strcmp(*argv, "-pubin") == 0)
! 175: pubin = 1;
! 176: else if (strcmp(*argv, "-pubout") == 0)
! 177: pubout = 1;
! 178: else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) {
! 179: BIO_printf(bio_err, "unknown option %s\n", *argv);
! 180: badops = 1;
! 181: break;
! 182: }
! 183: argc--;
! 184: argv++;
! 185: }
! 186:
! 187: if (badops) {
! 188: bad:
! 189: BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
! 190: BIO_printf(bio_err, "where options are\n");
! 191: BIO_printf(bio_err, " -inform arg input format - DER or PEM\n");
! 192: BIO_printf(bio_err, " -outform arg output format - DER or PEM\n");
! 193: BIO_printf(bio_err, " -in arg input file\n");
! 194: BIO_printf(bio_err, " -passin arg input file pass phrase source\n");
! 195: BIO_printf(bio_err, " -out arg output file\n");
! 196: BIO_printf(bio_err, " -passout arg output file pass phrase source\n");
! 197: #ifndef OPENSSL_NO_ENGINE
! 198: BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n");
! 199: #endif
! 200: BIO_printf(bio_err, " -des encrypt PEM output with cbc des\n");
! 201: BIO_printf(bio_err, " -des3 encrypt PEM output with ede cbc des using 168 bit key\n");
! 202: #ifndef OPENSSL_NO_IDEA
! 203: BIO_printf(bio_err, " -idea encrypt PEM output with cbc idea\n");
! 204: #endif
! 205: #ifndef OPENSSL_NO_AES
! 206: BIO_printf(bio_err, " -aes128, -aes192, -aes256\n");
! 207: BIO_printf(bio_err, " encrypt PEM output with cbc aes\n");
! 208: #endif
! 209: #ifndef OPENSSL_NO_CAMELLIA
! 210: BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n");
! 211: BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n");
! 212: #endif
! 213: BIO_printf(bio_err, " -text print the key in text\n");
! 214: BIO_printf(bio_err, " -noout don't print key out\n");
! 215: BIO_printf(bio_err, " -modulus print the DSA public value\n");
! 216: goto end;
! 217: }
! 218: ERR_load_crypto_strings();
! 219:
! 220: #ifndef OPENSSL_NO_ENGINE
! 221: e = setup_engine(bio_err, engine, 0);
! 222: #endif
! 223:
! 224: if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
! 225: BIO_printf(bio_err, "Error getting passwords\n");
! 226: goto end;
! 227: }
! 228: in = BIO_new(BIO_s_file());
! 229: out = BIO_new(BIO_s_file());
! 230: if ((in == NULL) || (out == NULL)) {
! 231: ERR_print_errors(bio_err);
! 232: goto end;
! 233: }
! 234: if (infile == NULL)
! 235: BIO_set_fp(in, stdin, BIO_NOCLOSE);
! 236: else {
! 237: if (BIO_read_filename(in, infile) <= 0) {
! 238: perror(infile);
! 239: goto end;
! 240: }
! 241: }
! 242:
! 243: BIO_printf(bio_err, "read DSA key\n");
! 244:
! 245: {
! 246: EVP_PKEY *pkey;
! 247:
! 248: if (pubin)
! 249: pkey = load_pubkey(bio_err, infile, informat, 1,
! 250: passin, e, "Public Key");
! 251: else
! 252: pkey = load_key(bio_err, infile, informat, 1,
! 253: passin, e, "Private Key");
! 254:
! 255: if (pkey) {
! 256: dsa = EVP_PKEY_get1_DSA(pkey);
! 257: EVP_PKEY_free(pkey);
! 258: }
! 259: }
! 260: if (dsa == NULL) {
! 261: BIO_printf(bio_err, "unable to load Key\n");
! 262: ERR_print_errors(bio_err);
! 263: goto end;
! 264: }
! 265: if (outfile == NULL) {
! 266: BIO_set_fp(out, stdout, BIO_NOCLOSE);
! 267: } else {
! 268: if (BIO_write_filename(out, outfile) <= 0) {
! 269: perror(outfile);
! 270: goto end;
! 271: }
! 272: }
! 273:
! 274: if (text) {
! 275: if (!DSA_print(out, dsa, 0)) {
! 276: perror(outfile);
! 277: ERR_print_errors(bio_err);
! 278: goto end;
! 279: }
! 280: }
! 281: if (modulus) {
! 282: fprintf(stdout, "Public Key=");
! 283: BN_print(out, dsa->pub_key);
! 284: fprintf(stdout, "\n");
! 285: }
! 286: if (noout)
! 287: goto end;
! 288: BIO_printf(bio_err, "writing DSA key\n");
! 289: if (outformat == FORMAT_ASN1) {
! 290: if (pubin || pubout)
! 291: i = i2d_DSA_PUBKEY_bio(out, dsa);
! 292: else
! 293: i = i2d_DSAPrivateKey_bio(out, dsa);
! 294: } else if (outformat == FORMAT_PEM) {
! 295: if (pubin || pubout)
! 296: i = PEM_write_bio_DSA_PUBKEY(out, dsa);
! 297: else
! 298: i = PEM_write_bio_DSAPrivateKey(out, dsa, enc,
! 299: NULL, 0, NULL, passout);
! 300: #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
! 301: } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
! 302: EVP_PKEY *pk;
! 303: pk = EVP_PKEY_new();
! 304: EVP_PKEY_set1_DSA(pk, dsa);
! 305: if (outformat == FORMAT_PVK)
! 306: i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
! 307: else if (pubin || pubout)
! 308: i = i2b_PublicKey_bio(out, pk);
! 309: else
! 310: i = i2b_PrivateKey_bio(out, pk);
! 311: EVP_PKEY_free(pk);
! 312: #endif
! 313: } else {
! 314: BIO_printf(bio_err, "bad output format specified for outfile\n");
! 315: goto end;
! 316: }
! 317: if (i <= 0) {
! 318: BIO_printf(bio_err, "unable to write private key\n");
! 319: ERR_print_errors(bio_err);
! 320: } else
! 321: ret = 0;
! 322: end:
! 323: BIO_free(in);
! 324: if (out != NULL)
! 325: BIO_free_all(out);
! 326: if (dsa != NULL)
! 327: DSA_free(dsa);
! 328: free(passin);
! 329: free(passout);
! 330:
! 331: return (ret);
! 332: }