Replumbing: pre-populate the EVP namemap with commonly known names
[openssl.git] / apps / genrsa.c
1 /*
2  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 verbose = 0;
34
35 static int genrsa_cb(int p, int n, BN_GENCB *cb);
36
37 typedef enum OPTION_choice {
38     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
39     OPT_3, OPT_F4, OPT_ENGINE,
40     OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE,
41     OPT_R_ENUM
42 } OPTION_CHOICE;
43
44 const OPTIONS genrsa_options[] = {
45     {OPT_HELP_STR, 1, '-', "Usage: %s [options] numbits\n"},
46
47     OPT_SECTION("General"),
48     {"help", OPT_HELP, '-', "Display this summary"},
49 # ifndef OPENSSL_NO_ENGINE
50     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
51 # endif
52
53     OPT_SECTION("Input"),
54     {"3", OPT_3, '-', "Use 3 for the E value"},
55     {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
56     {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
57
58     OPT_SECTION("Output"),
59     {"out", OPT_OUT, '>', "Output the key to specified file"},
60     {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
61     {"primes", OPT_PRIMES, 'p', "Specify number of primes"},
62     {"verbose", OPT_VERBOSE, '-', "Verbose output"},
63     {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
64
65     OPT_R_OPTIONS,
66
67     OPT_PARAMETERS(),
68     {"numbits", 0, 0, "Size of key in bits"},
69     {NULL}
70 };
71
72 int genrsa_main(int argc, char **argv)
73 {
74     BN_GENCB *cb = BN_GENCB_new();
75     PW_CB_DATA cb_data;
76     ENGINE *eng = NULL;
77     BIGNUM *bn = BN_new();
78     BIO *out = NULL;
79     const BIGNUM *e;
80     RSA *rsa = NULL;
81     const EVP_CIPHER *enc = NULL;
82     int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES;
83     unsigned long f4 = RSA_F4;
84     char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
85     char *prog, *hexe, *dece;
86     OPTION_CHOICE o;
87
88     if (bn == NULL || cb == NULL)
89         goto end;
90
91     BN_GENCB_set(cb, genrsa_cb, bio_err);
92
93     prog = opt_init(argc, argv, genrsa_options);
94     while ((o = opt_next()) != OPT_EOF) {
95         switch (o) {
96         case OPT_EOF:
97         case OPT_ERR:
98 opthelp:
99             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
100             goto end;
101         case OPT_HELP:
102             ret = 0;
103             opt_help(genrsa_options);
104             goto end;
105         case OPT_3:
106             f4 = 3;
107             break;
108         case OPT_F4:
109             f4 = RSA_F4;
110             break;
111         case OPT_OUT:
112             outfile = opt_arg();
113             break;
114         case OPT_ENGINE:
115             eng = setup_engine(opt_arg(), 0);
116             break;
117         case OPT_R_CASES:
118             if (!opt_rand(o))
119                 goto end;
120             break;
121         case OPT_PASSOUT:
122             passoutarg = opt_arg();
123             break;
124         case OPT_CIPHER:
125             if (!opt_cipher(opt_unknown(), &enc))
126                 goto end;
127             break;
128         case OPT_PRIMES:
129             if (!opt_int(opt_arg(), &primes))
130                 goto end;
131             break;
132         case OPT_VERBOSE:
133             verbose = 1;
134             break;
135         }
136     }
137     argc = opt_num_rest();
138     argv = opt_rest();
139
140     if (argc == 1) {
141         if (!opt_int(argv[0], &num) || num <= 0)
142             goto end;
143         if (num > OPENSSL_RSA_MAX_MODULUS_BITS)
144             BIO_printf(bio_err,
145                        "Warning: It is not recommended to use more than %d bit for RSA keys.\n"
146                        "         Your key size is %d! Larger key size may behave not as expected.\n",
147                        OPENSSL_RSA_MAX_MODULUS_BITS, num);
148     } else if (argc > 0) {
149         BIO_printf(bio_err, "Extra arguments given.\n");
150         goto opthelp;
151     }
152
153     private = 1;
154     if (!app_passwd(NULL, passoutarg, NULL, &passout)) {
155         BIO_printf(bio_err, "Error getting password\n");
156         goto end;
157     }
158
159     out = bio_open_owner(outfile, FORMAT_PEM, private);
160     if (out == NULL)
161         goto end;
162
163     if (verbose)
164         BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
165                    num, primes);
166     rsa = eng ? RSA_new_method(eng) : RSA_new();
167     if (rsa == NULL)
168         goto end;
169
170     if (!BN_set_word(bn, f4)
171         || !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb))
172         goto end;
173
174     RSA_get0_key(rsa, NULL, &e, NULL);
175     hexe = BN_bn2hex(e);
176     dece = BN_bn2dec(e);
177     if (hexe && dece && verbose) {
178         BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
179     }
180     OPENSSL_free(hexe);
181     OPENSSL_free(dece);
182     cb_data.password = passout;
183     cb_data.prompt_info = outfile;
184     assert(private);
185     if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
186                                      (pem_password_cb *)password_callback,
187                                      &cb_data))
188         goto end;
189
190     ret = 0;
191  end:
192     BN_free(bn);
193     BN_GENCB_free(cb);
194     RSA_free(rsa);
195     BIO_free_all(out);
196     release_engine(eng);
197     OPENSSL_free(passout);
198     if (ret != 0)
199         ERR_print_errors(bio_err);
200     return ret;
201 }
202
203 static int genrsa_cb(int p, int n, BN_GENCB *cb)
204 {
205     char c = '*';
206
207     if (!verbose)
208         return 1;
209
210     if (p == 0)
211         c = '.';
212     if (p == 1)
213         c = '+';
214     if (p == 2)
215         c = '*';
216     if (p == 3)
217         c = '\n';
218     BIO_write(BN_GENCB_get_arg(cb), &c, 1);
219     (void)BIO_flush(BN_GENCB_get_arg(cb));
220     return 1;
221 }
222 #endif