summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/genrsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr.bin/openssl/genrsa.c')
-rw-r--r--src/usr.bin/openssl/genrsa.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/usr.bin/openssl/genrsa.c b/src/usr.bin/openssl/genrsa.c
new file mode 100644
index 0000000000..7844fb815f
--- /dev/null
+++ b/src/usr.bin/openssl/genrsa.c
@@ -0,0 +1,286 @@
1/* $OpenBSD: genrsa.c,v 1.1 2014/08/26 17:47:24 jsing 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>
60
61/* Until the key-gen callbacks are modified to use newer prototypes, we allow
62 * deprecated functions for openssl-internal code */
63#ifdef OPENSSL_NO_DEPRECATED
64#undef OPENSSL_NO_DEPRECATED
65#endif
66
67
68#include <sys/types.h>
69#include <sys/stat.h>
70
71#include <stdio.h>
72#include <string.h>
73
74#include "apps.h"
75
76#include <openssl/bio.h>
77#include <openssl/bn.h>
78#include <openssl/err.h>
79#include <openssl/evp.h>
80#include <openssl/pem.h>
81#include <openssl/rand.h>
82#include <openssl/rsa.h>
83#include <openssl/x509.h>
84
85#define DEFBITS 2048
86
87static int genrsa_cb(int p, int n, BN_GENCB * cb);
88
89int genrsa_main(int, char **);
90
91int
92genrsa_main(int argc, char **argv)
93{
94 BN_GENCB cb;
95#ifndef OPENSSL_NO_ENGINE
96 ENGINE *e = NULL;
97#endif
98 int ret = 1;
99 int i, num = DEFBITS;
100 long l;
101 const EVP_CIPHER *enc = NULL;
102 unsigned long f4 = RSA_F4;
103 char *outfile = NULL;
104 char *passargout = NULL, *passout = NULL;
105#ifndef OPENSSL_NO_ENGINE
106 char *engine = NULL;
107#endif
108 BIO *out = NULL;
109 BIGNUM *bn = BN_new();
110 RSA *rsa = NULL;
111
112 if (!bn)
113 goto err;
114
115 BN_GENCB_set(&cb, genrsa_cb, bio_err);
116
117 if ((out = BIO_new(BIO_s_file())) == NULL) {
118 BIO_printf(bio_err, "unable to create BIO for output\n");
119 goto err;
120 }
121 argv++;
122 argc--;
123 for (;;) {
124 if (argc <= 0)
125 break;
126 if (strcmp(*argv, "-out") == 0) {
127 if (--argc < 1)
128 goto bad;
129 outfile = *(++argv);
130 } else if (strcmp(*argv, "-3") == 0)
131 f4 = 3;
132 else if (strcmp(*argv, "-F4") == 0 || strcmp(*argv, "-f4") == 0)
133 f4 = RSA_F4;
134#ifndef OPENSSL_NO_ENGINE
135 else if (strcmp(*argv, "-engine") == 0) {
136 if (--argc < 1)
137 goto bad;
138 engine = *(++argv);
139 }
140#endif
141#ifndef OPENSSL_NO_DES
142 else if (strcmp(*argv, "-des") == 0)
143 enc = EVP_des_cbc();
144 else if (strcmp(*argv, "-des3") == 0)
145 enc = EVP_des_ede3_cbc();
146#endif
147#ifndef OPENSSL_NO_IDEA
148 else if (strcmp(*argv, "-idea") == 0)
149 enc = EVP_idea_cbc();
150#endif
151#ifndef OPENSSL_NO_AES
152 else if (strcmp(*argv, "-aes128") == 0)
153 enc = EVP_aes_128_cbc();
154 else if (strcmp(*argv, "-aes192") == 0)
155 enc = EVP_aes_192_cbc();
156 else if (strcmp(*argv, "-aes256") == 0)
157 enc = EVP_aes_256_cbc();
158#endif
159#ifndef OPENSSL_NO_CAMELLIA
160 else if (strcmp(*argv, "-camellia128") == 0)
161 enc = EVP_camellia_128_cbc();
162 else if (strcmp(*argv, "-camellia192") == 0)
163 enc = EVP_camellia_192_cbc();
164 else if (strcmp(*argv, "-camellia256") == 0)
165 enc = EVP_camellia_256_cbc();
166#endif
167 else if (strcmp(*argv, "-passout") == 0) {
168 if (--argc < 1)
169 goto bad;
170 passargout = *(++argv);
171 } else
172 break;
173 argv++;
174 argc--;
175 }
176 if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) {
177bad:
178 BIO_printf(bio_err, "usage: genrsa [args] [numbits]\n");
179 BIO_printf(bio_err, " -des encrypt the generated key with DES in cbc mode\n");
180 BIO_printf(bio_err, " -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
181#ifndef OPENSSL_NO_IDEA
182 BIO_printf(bio_err, " -idea encrypt the generated key with IDEA in cbc mode\n");
183#endif
184#ifndef OPENSSL_NO_AES
185 BIO_printf(bio_err, " -aes128, -aes192, -aes256\n");
186 BIO_printf(bio_err, " encrypt PEM output with cbc aes\n");
187#endif
188#ifndef OPENSSL_NO_CAMELLIA
189 BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n");
190 BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n");
191#endif
192 BIO_printf(bio_err, " -out file output the key to 'file\n");
193 BIO_printf(bio_err, " -passout arg output file pass phrase source\n");
194 BIO_printf(bio_err, " -f4 use F4 (0x10001) for the E value\n");
195 BIO_printf(bio_err, " -3 use 3 for the E value\n");
196#ifndef OPENSSL_NO_ENGINE
197 BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n");
198#endif
199 goto err;
200 }
201 ERR_load_crypto_strings();
202
203 if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
204 BIO_printf(bio_err, "Error getting password\n");
205 goto err;
206 }
207#ifndef OPENSSL_NO_ENGINE
208 e = setup_engine(bio_err, engine, 0);
209#endif
210
211 if (outfile == NULL) {
212 BIO_set_fp(out, stdout, BIO_NOCLOSE);
213 } else {
214 if (BIO_write_filename(out, outfile) <= 0) {
215 perror(outfile);
216 goto err;
217 }
218 }
219
220 BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
221 num);
222#ifdef OPENSSL_NO_ENGINE
223 rsa = RSA_new();
224#else
225 rsa = RSA_new_method(e);
226#endif
227 if (!rsa)
228 goto err;
229
230 if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
231 goto err;
232
233 /*
234 * We need to do the following for when the base number size is <
235 * long, esp windows 3.1 :-(.
236 */
237 l = 0L;
238 for (i = 0; i < rsa->e->top; i++) {
239#ifndef _LP64
240 l <<= BN_BITS4;
241 l <<= BN_BITS4;
242#endif
243 l += rsa->e->d[i];
244 }
245 BIO_printf(bio_err, "e is %ld (0x%lX)\n", l, l);
246 {
247 PW_CB_DATA cb_data;
248 cb_data.password = passout;
249 cb_data.prompt_info = outfile;
250 if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
251 password_callback, &cb_data))
252 goto err;
253 }
254
255 ret = 0;
256err:
257 if (bn)
258 BN_free(bn);
259 if (rsa)
260 RSA_free(rsa);
261 if (out)
262 BIO_free_all(out);
263 free(passout);
264 if (ret != 0)
265 ERR_print_errors(bio_err);
266
267 return (ret);
268}
269
270static int
271genrsa_cb(int p, int n, BN_GENCB * cb)
272{
273 char c = '*';
274
275 if (p == 0)
276 c = '.';
277 if (p == 1)
278 c = '+';
279 if (p == 2)
280 c = '*';
281 if (p == 3)
282 c = '\n';
283 BIO_write(cb->arg, &c, 1);
284 (void) BIO_flush(cb->arg);
285 return 1;
286}