1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <openssl/opensslconf.h> 11 #ifdef OPENSSL_NO_RSA 12 NON_EMPTY_TRANSLATION_UNIT 13 #else 14 15 # include <stdio.h> 16 # include <string.h> 17 # include <sys/types.h> 18 # include <sys/stat.h> 19 # include "apps.h" 20 # include "progs.h" 21 # include <openssl/bio.h> 22 # include <openssl/err.h> 23 # include <openssl/bn.h> 24 # include <openssl/rsa.h> 25 # include <openssl/evp.h> 26 # include <openssl/x509.h> 27 # include <openssl/pem.h> 28 # include <openssl/rand.h> 29 30 # define DEFBITS 2048 31 # define DEFPRIMES 2 32 33 static int genrsa_cb(int p, int n, BN_GENCB *cb); 34 35 typedef enum OPTION_choice { 36 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 37 OPT_3, OPT_F4, OPT_ENGINE, 38 OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, 39 OPT_R_ENUM 40 } OPTION_CHOICE; 41 42 const OPTIONS genrsa_options[] = { 43 {"help", OPT_HELP, '-', "Display this summary"}, 44 {"3", OPT_3, '-', "Use 3 for the E value"}, 45 {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, 46 {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, 47 {"out", OPT_OUT, '>', "Output the key to specified file"}, 48 OPT_R_OPTIONS, 49 {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, 50 {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, 51 # ifndef OPENSSL_NO_ENGINE 52 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 53 # endif 54 {"primes", OPT_PRIMES, 'p', "Specify number of primes"}, 55 {NULL} 56 }; 57 58 int genrsa_main(int argc, char **argv) 59 { 60 BN_GENCB *cb = BN_GENCB_new(); 61 PW_CB_DATA cb_data; 62 ENGINE *eng = NULL; 63 BIGNUM *bn = BN_new(); 64 BIO *out = NULL; 65 const BIGNUM *e; 66 RSA *rsa = NULL; 67 const EVP_CIPHER *enc = NULL; 68 int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES; 69 unsigned long f4 = RSA_F4; 70 char *outfile = NULL, *passoutarg = NULL, *passout = NULL; 71 char *prog, *hexe, *dece; 72 OPTION_CHOICE o; 73 74 if (bn == NULL || cb == NULL) 75 goto end; 76 77 BN_GENCB_set(cb, genrsa_cb, bio_err); 78 79 prog = opt_init(argc, argv, genrsa_options); 80 while ((o = opt_next()) != OPT_EOF) { 81 switch (o) { 82 case OPT_EOF: 83 case OPT_ERR: 84 opthelp: 85 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 86 goto end; 87 case OPT_HELP: 88 ret = 0; 89 opt_help(genrsa_options); 90 goto end; 91 case OPT_3: 92 f4 = 3; 93 break; 94 case OPT_F4: 95 f4 = RSA_F4; 96 break; 97 case OPT_OUT: 98 outfile = opt_arg(); 99 break; 100 case OPT_ENGINE: 101 eng = setup_engine(opt_arg(), 0); 102 break; 103 case OPT_R_CASES: 104 if (!opt_rand(o)) 105 goto end; 106 break; 107 case OPT_PASSOUT: 108 passoutarg = opt_arg(); 109 break; 110 case OPT_CIPHER: 111 if (!opt_cipher(opt_unknown(), &enc)) 112 goto end; 113 break; 114 case OPT_PRIMES: 115 if (!opt_int(opt_arg(), &primes)) 116 goto end; 117 break; 118 } 119 } 120 argc = opt_num_rest(); 121 argv = opt_rest(); 122 123 if (argc == 1) { 124 if (!opt_int(argv[0], &num) || num <= 0) 125 goto end; 126 if (num > OPENSSL_RSA_MAX_MODULUS_BITS) 127 BIO_printf(bio_err, 128 "Warning: It is not recommended to use more than %d bit for RSA keys.\n" 129 " Your key size is %d! Larger key size may behave not as expected.\n", 130 OPENSSL_RSA_MAX_MODULUS_BITS, num); 131 } else if (argc > 0) { 132 BIO_printf(bio_err, "Extra arguments given.\n"); 133 goto opthelp; 134 } 135 136 private = 1; 137 if (!app_passwd(NULL, passoutarg, NULL, &passout)) { 138 BIO_printf(bio_err, "Error getting password\n"); 139 goto end; 140 } 141 142 out = bio_open_owner(outfile, FORMAT_PEM, private); 143 if (out == NULL) 144 goto end; 145 146 BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n", 147 num, primes); 148 rsa = eng ? RSA_new_method(eng) : RSA_new(); 149 if (rsa == NULL) 150 goto end; 151 152 if (!BN_set_word(bn, f4) 153 || !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb)) 154 goto end; 155 156 RSA_get0_key(rsa, NULL, &e, NULL); 157 hexe = BN_bn2hex(e); 158 dece = BN_bn2dec(e); 159 if (hexe && dece) { 160 BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe); 161 } 162 OPENSSL_free(hexe); 163 OPENSSL_free(dece); 164 cb_data.password = passout; 165 cb_data.prompt_info = outfile; 166 assert(private); 167 if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, 168 (pem_password_cb *)password_callback, 169 &cb_data)) 170 goto end; 171 172 ret = 0; 173 end: 174 BN_free(bn); 175 BN_GENCB_free(cb); 176 RSA_free(rsa); 177 BIO_free_all(out); 178 release_engine(eng); 179 OPENSSL_free(passout); 180 if (ret != 0) 181 ERR_print_errors(bio_err); 182 return ret; 183 } 184 185 static int genrsa_cb(int p, int n, BN_GENCB *cb) 186 { 187 char c = '*'; 188 189 if (p == 0) 190 c = '.'; 191 if (p == 1) 192 c = '+'; 193 if (p == 2) 194 c = '*'; 195 if (p == 3) 196 c = '\n'; 197 BIO_write(BN_GENCB_get_arg(cb), &c, 1); 198 (void)BIO_flush(BN_GENCB_get_arg(cb)); 199 return 1; 200 } 201 #endif 202