]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/genrsa.c
Add "sections" to -help output
[thirdparty/openssl.git] / apps / genrsa.c
CommitLineData
846e33c7 1/*
6738bf14 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
dffa7520 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
846e33c7
RS
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
d02b48c6
RE
8 */
9
3eeaab4b 10#include <openssl/opensslconf.h>
effaf4de
RS
11#ifdef OPENSSL_NO_RSA
12NON_EMPTY_TRANSLATION_UNIT
13#else
5daec7ea 14
0f113f3e
MC
15# include <stdio.h>
16# include <string.h>
17# include <sys/types.h>
18# include <sys/stat.h>
19# include "apps.h"
dab2cd68 20# include "progs.h"
0f113f3e
MC
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>
d02b48c6 29
0f113f3e 30# define DEFBITS 2048
665d899f 31# define DEFPRIMES 2
d02b48c6 32
c43fa566
PP
33static int verbose = 0;
34
6d23cf97 35static int genrsa_cb(int p, int n, BN_GENCB *cb);
667ac4ec 36
7e1b7485
RS
37typedef enum OPTION_choice {
38 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
700b4a4a 39 OPT_3, OPT_F4, OPT_ENGINE,
c43fa566 40 OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE,
3ee1eac2 41 OPT_R_ENUM
7e1b7485 42} OPTION_CHOICE;
667ac4ec 43
44c83ebd 44const OPTIONS genrsa_options[] = {
5388f986
RS
45
46 OPT_SECTION("General"),
7e1b7485 47 {"help", OPT_HELP, '-', "Display this summary"},
5388f986
RS
48# ifndef OPENSSL_NO_ENGINE
49 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
50# endif
51
52 OPT_SECTION("Input"),
7e1b7485
RS
53 {"3", OPT_3, '-', "Use 3 for the E value"},
54 {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
55 {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
5388f986
RS
56
57 OPT_SECTION("Output"),
6f007824 58 {"out", OPT_OUT, '>', "Output the key to specified file"},
7e1b7485 59 {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
665d899f 60 {"primes", OPT_PRIMES, 'p', "Specify number of primes"},
c43fa566 61 {"verbose", OPT_VERBOSE, '-', "Verbose output"},
5388f986
RS
62 {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
63
64 OPT_R_OPTIONS,
7e1b7485
RS
65 {NULL}
66};
67
68int genrsa_main(int argc, char **argv)
69{
70 BN_GENCB *cb = BN_GENCB_new();
3b061a00 71 PW_CB_DATA cb_data;
9862e9aa 72 ENGINE *eng = NULL;
7e1b7485
RS
73 BIGNUM *bn = BN_new();
74 BIO *out = NULL;
2ac6115d 75 const BIGNUM *e;
7e1b7485 76 RSA *rsa = NULL;
0f113f3e 77 const EVP_CIPHER *enc = NULL;
665d899f 78 int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES;
0f113f3e 79 unsigned long f4 = RSA_F4;
7e1b7485 80 char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
3ee1eac2 81 char *prog, *hexe, *dece;
7e1b7485 82 OPTION_CHOICE o;
348d0d14 83
96487cdd 84 if (bn == NULL || cb == NULL)
7e1b7485 85 goto end;
348d0d14 86
0f113f3e 87 BN_GENCB_set(cb, genrsa_cb, bio_err);
d02b48c6 88
7e1b7485
RS
89 prog = opt_init(argc, argv, genrsa_options);
90 while ((o = opt_next()) != OPT_EOF) {
91 switch (o) {
92 case OPT_EOF:
93 case OPT_ERR:
c27363f5 94opthelp:
7e1b7485
RS
95 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
96 goto end;
97 case OPT_HELP:
98 ret = 0;
99 opt_help(genrsa_options);
100 goto end;
101 case OPT_3:
0f113f3e 102 f4 = 3;
7e1b7485
RS
103 break;
104 case OPT_F4:
0f113f3e 105 f4 = RSA_F4;
7e1b7485 106 break;
7e1b7485
RS
107 case OPT_OUT:
108 outfile = opt_arg();
902c6b95 109 break;
7e1b7485 110 case OPT_ENGINE:
9862e9aa 111 eng = setup_engine(opt_arg(), 0);
7e1b7485 112 break;
3ee1eac2
RS
113 case OPT_R_CASES:
114 if (!opt_rand(o))
115 goto end;
7e1b7485
RS
116 break;
117 case OPT_PASSOUT:
118 passoutarg = opt_arg();
119 break;
120 case OPT_CIPHER:
121 if (!opt_cipher(opt_unknown(), &enc))
122 goto end;
123 break;
665d899f
PY
124 case OPT_PRIMES:
125 if (!opt_int(opt_arg(), &primes))
126 goto end;
127 break;
c43fa566
PP
128 case OPT_VERBOSE:
129 verbose = 1;
130 break;
7e1b7485 131 }
0f113f3e 132 }
7e1b7485
RS
133 argc = opt_num_rest();
134 argv = opt_rest();
a3fe382e 135
c27363f5
RS
136 if (argc == 1) {
137 if (!opt_int(argv[0], &num) || num <= 0)
138 goto end;
0336df2f
GS
139 if (num > OPENSSL_RSA_MAX_MODULUS_BITS)
140 BIO_printf(bio_err,
141 "Warning: It is not recommended to use more than %d bit for RSA keys.\n"
142 " Your key size is %d! Larger key size may behave not as expected.\n",
143 OPENSSL_RSA_MAX_MODULUS_BITS, num);
c27363f5
RS
144 } else if (argc > 0) {
145 BIO_printf(bio_err, "Extra arguments given.\n");
146 goto opthelp;
147 }
a3fe382e 148
c27363f5 149 private = 1;
7e1b7485 150 if (!app_passwd(NULL, passoutarg, NULL, &passout)) {
0f113f3e 151 BIO_printf(bio_err, "Error getting password\n");
7e1b7485 152 goto end;
0f113f3e 153 }
5270e702 154
bdd58d98 155 out = bio_open_owner(outfile, FORMAT_PEM, private);
7e1b7485
RS
156 if (out == NULL)
157 goto end;
d02b48c6 158
c43fa566
PP
159 if (verbose)
160 BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
161 num, primes);
9862e9aa 162 rsa = eng ? RSA_new_method(eng) : RSA_new();
96487cdd 163 if (rsa == NULL)
7e1b7485 164 goto end;
0f113f3e 165
665d899f
PY
166 if (!BN_set_word(bn, f4)
167 || !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb))
7e1b7485 168 goto end;
dc03504d 169
9862e9aa
RL
170 RSA_get0_key(rsa, NULL, &e, NULL);
171 hexe = BN_bn2hex(e);
172 dece = BN_bn2dec(e);
c43fa566 173 if (hexe && dece && verbose) {
0f113f3e
MC
174 BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
175 }
25aaa98a
RS
176 OPENSSL_free(hexe);
177 OPENSSL_free(dece);
3b061a00
RS
178 cb_data.password = passout;
179 cb_data.prompt_info = outfile;
180 assert(private);
181 if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
182 (pem_password_cb *)password_callback,
183 &cb_data))
184 goto end;
d02b48c6 185
0f113f3e 186 ret = 0;
7e1b7485 187 end:
23a1d5e9
RS
188 BN_free(bn);
189 BN_GENCB_free(cb);
d6407083 190 RSA_free(rsa);
ca3a82c3 191 BIO_free_all(out);
dd1abd44 192 release_engine(eng);
b548a1f1 193 OPENSSL_free(passout);
0f113f3e
MC
194 if (ret != 0)
195 ERR_print_errors(bio_err);
26a7d938 196 return ret;
0f113f3e 197}
d02b48c6 198
6d23cf97 199static int genrsa_cb(int p, int n, BN_GENCB *cb)
0f113f3e
MC
200{
201 char c = '*';
d02b48c6 202
c43fa566
PP
203 if (!verbose)
204 return 1;
205
0f113f3e
MC
206 if (p == 0)
207 c = '.';
208 if (p == 1)
209 c = '+';
210 if (p == 2)
211 c = '*';
212 if (p == 3)
213 c = '\n';
214 BIO_write(BN_GENCB_get_arg(cb), &c, 1);
215 (void)BIO_flush(BN_GENCB_get_arg(cb));
216 return 1;
217}
f5d7a031 218#endif