1 1.1.1.2 christos /* 2 1.1.1.2 christos * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1.1.2 christos * Licensed under the OpenSSL license (the "License"). You may not use 5 1.1.1.2 christos * this file except in compliance with the License. You can obtain a copy 6 1.1.1.2 christos * in the file LICENSE in the source distribution or at 7 1.1.1.2 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1.1.2 christos #include <openssl/opensslconf.h> 11 1.1.1.2 christos #include <stdio.h> 12 1.1.1.2 christos #include <string.h> 13 1.1.1.2 christos #include <sys/types.h> 14 1.1.1.2 christos #include <sys/stat.h> 15 1.1.1.2 christos #include "apps.h" 16 1.1.1.2 christos #include "progs.h" 17 1.1.1.2 christos #include <openssl/bio.h> 18 1.1.1.2 christos #include <openssl/err.h> 19 1.1.1.2 christos #include <openssl/bn.h> 20 1.1.1.2 christos #include <openssl/dsa.h> 21 1.1.1.2 christos #include <openssl/x509.h> 22 1.1.1.2 christos #include <openssl/pem.h> 23 1.1.1.2 christos 24 1.1.1.2 christos typedef enum OPTION_choice { 25 1.1.1.2 christos OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 26 1.1.1.2 christos OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER, 27 1.1.1.2 christos OPT_R_ENUM 28 1.1.1.2 christos } OPTION_CHOICE; 29 1.1.1.2 christos 30 1.1.1.2 christos const OPTIONS gendsa_options[] = { 31 1.1.1.2 christos {OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"}, 32 1.1.1.2 christos {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, 33 1.1.1.2 christos {"help", OPT_HELP, '-', "Display this summary"}, 34 1.1.1.2 christos {"out", OPT_OUT, '>', "Output the key to the specified file"}, 35 1.1.1.2 christos {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, 36 1.1.1.2 christos OPT_R_OPTIONS, 37 1.1.1.2 christos {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, 38 1.1.1.2 christos #ifndef OPENSSL_NO_ENGINE 39 1.1.1.2 christos {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 40 1.1.1.2 christos #endif 41 1.1.1.2 christos {NULL} 42 1.1.1.2 christos }; 43 1.1 christos 44 1.1.1.2 christos int gendsa_main(int argc, char **argv) 45 1.1 christos { 46 1.1.1.2 christos ENGINE *e = NULL; 47 1.1 christos BIO *out = NULL, *in = NULL; 48 1.1.1.2 christos DSA *dsa = NULL; 49 1.1 christos const EVP_CIPHER *enc = NULL; 50 1.1.1.2 christos char *dsaparams = NULL; 51 1.1.1.2 christos char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog; 52 1.1.1.2 christos OPTION_CHOICE o; 53 1.1.1.2 christos int ret = 1, private = 0; 54 1.1.1.2 christos const BIGNUM *p = NULL; 55 1.1.1.2 christos 56 1.1.1.2 christos prog = opt_init(argc, argv, gendsa_options); 57 1.1.1.2 christos while ((o = opt_next()) != OPT_EOF) { 58 1.1.1.2 christos switch (o) { 59 1.1.1.2 christos case OPT_EOF: 60 1.1.1.2 christos case OPT_ERR: 61 1.1.1.2 christos opthelp: 62 1.1.1.2 christos BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 63 1.1.1.2 christos goto end; 64 1.1.1.2 christos case OPT_HELP: 65 1.1.1.2 christos ret = 0; 66 1.1.1.2 christos opt_help(gendsa_options); 67 1.1.1.2 christos goto end; 68 1.1.1.2 christos case OPT_OUT: 69 1.1.1.2 christos outfile = opt_arg(); 70 1.1.1.2 christos break; 71 1.1.1.2 christos case OPT_PASSOUT: 72 1.1.1.2 christos passoutarg = opt_arg(); 73 1.1.1.2 christos break; 74 1.1.1.2 christos case OPT_ENGINE: 75 1.1.1.2 christos e = setup_engine(opt_arg(), 0); 76 1.1.1.2 christos break; 77 1.1.1.2 christos case OPT_R_CASES: 78 1.1.1.2 christos if (!opt_rand(o)) 79 1.1.1.2 christos goto end; 80 1.1.1.2 christos break; 81 1.1.1.2 christos case OPT_CIPHER: 82 1.1.1.2 christos if (!opt_cipher(opt_unknown(), &enc)) 83 1.1.1.2 christos goto end; 84 1.1 christos break; 85 1.1 christos } 86 1.1 christos } 87 1.1.1.2 christos argc = opt_num_rest(); 88 1.1.1.2 christos argv = opt_rest(); 89 1.1.1.2 christos private = 1; 90 1.1.1.2 christos 91 1.1.1.2 christos if (argc != 1) 92 1.1.1.2 christos goto opthelp; 93 1.1.1.2 christos dsaparams = *argv; 94 1.1 christos 95 1.1.1.2 christos if (!app_passwd(NULL, passoutarg, NULL, &passout)) { 96 1.1 christos BIO_printf(bio_err, "Error getting password\n"); 97 1.1 christos goto end; 98 1.1 christos } 99 1.1 christos 100 1.1.1.2 christos in = bio_open_default(dsaparams, 'r', FORMAT_PEM); 101 1.1.1.2 christos if (in == NULL) 102 1.1.1.2 christos goto end2; 103 1.1 christos 104 1.1 christos if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) { 105 1.1 christos BIO_printf(bio_err, "unable to load DSA parameter file\n"); 106 1.1 christos goto end; 107 1.1 christos } 108 1.1 christos BIO_free(in); 109 1.1 christos in = NULL; 110 1.1 christos 111 1.1.1.2 christos out = bio_open_owner(outfile, FORMAT_PEM, private); 112 1.1 christos if (out == NULL) 113 1.1.1.2 christos goto end2; 114 1.1 christos 115 1.1.1.2 christos DSA_get0_pqg(dsa, &p, NULL, NULL); 116 1.1 christos 117 1.1.1.2 christos if (BN_num_bits(p) > OPENSSL_DSA_MAX_MODULUS_BITS) 118 1.1 christos BIO_printf(bio_err, 119 1.1.1.2 christos "Warning: It is not recommended to use more than %d bit for DSA keys.\n" 120 1.1.1.2 christos " Your key size is %d! Larger key size may behave not as expected.\n", 121 1.1.1.2 christos OPENSSL_DSA_MAX_MODULUS_BITS, BN_num_bits(p)); 122 1.1 christos 123 1.1.1.2 christos BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p)); 124 1.1 christos if (!DSA_generate_key(dsa)) 125 1.1 christos goto end; 126 1.1 christos 127 1.1.1.2 christos assert(private); 128 1.1 christos if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout)) 129 1.1 christos goto end; 130 1.1 christos ret = 0; 131 1.1 christos end: 132 1.1 christos if (ret != 0) 133 1.1 christos ERR_print_errors(bio_err); 134 1.1.1.2 christos end2: 135 1.1.1.2 christos BIO_free(in); 136 1.1.1.2 christos BIO_free_all(out); 137 1.1.1.2 christos DSA_free(dsa); 138 1.1 christos release_engine(e); 139 1.1.1.2 christos OPENSSL_free(passout); 140 1.1.1.2 christos return ret; 141 1.1 christos } 142