diff options
Diffstat (limited to 'src/usr.bin/openssl/rsautl.c')
-rw-r--r-- | src/usr.bin/openssl/rsautl.c | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/src/usr.bin/openssl/rsautl.c b/src/usr.bin/openssl/rsautl.c new file mode 100644 index 0000000000..7c83f1a82c --- /dev/null +++ b/src/usr.bin/openssl/rsautl.c | |||
@@ -0,0 +1,341 @@ | |||
1 | /* $OpenBSD: rsautl.c,v 1.1 2014/08/26 17:47:25 jsing Exp $ */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 2000. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 2000 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <openssl/opensslconf.h> | ||
60 | |||
61 | |||
62 | #include <string.h> | ||
63 | |||
64 | #include "apps.h" | ||
65 | |||
66 | #include <openssl/err.h> | ||
67 | #include <openssl/pem.h> | ||
68 | #include <openssl/rsa.h> | ||
69 | |||
70 | #define RSA_SIGN 1 | ||
71 | #define RSA_VERIFY 2 | ||
72 | #define RSA_ENCRYPT 3 | ||
73 | #define RSA_DECRYPT 4 | ||
74 | |||
75 | #define KEY_PRIVKEY 1 | ||
76 | #define KEY_PUBKEY 2 | ||
77 | #define KEY_CERT 3 | ||
78 | |||
79 | static void usage(void); | ||
80 | |||
81 | int rsautl_main(int argc, char **); | ||
82 | |||
83 | int | ||
84 | rsautl_main(int argc, char **argv) | ||
85 | { | ||
86 | ENGINE *e = NULL; | ||
87 | BIO *in = NULL, *out = NULL; | ||
88 | char *infile = NULL, *outfile = NULL; | ||
89 | #ifndef OPENSSL_NO_ENGINE | ||
90 | char *engine = NULL; | ||
91 | #endif | ||
92 | char *keyfile = NULL; | ||
93 | char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; | ||
94 | int keyform = FORMAT_PEM; | ||
95 | char need_priv = 0, badarg = 0, rev = 0; | ||
96 | char hexdump = 0, asn1parse = 0; | ||
97 | X509 *x; | ||
98 | EVP_PKEY *pkey = NULL; | ||
99 | RSA *rsa = NULL; | ||
100 | unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; | ||
101 | char *passargin = NULL, *passin = NULL; | ||
102 | int rsa_inlen, rsa_outlen = 0; | ||
103 | int keysize; | ||
104 | |||
105 | int ret = 1; | ||
106 | |||
107 | argc--; | ||
108 | argv++; | ||
109 | |||
110 | ERR_load_crypto_strings(); | ||
111 | OpenSSL_add_all_algorithms(); | ||
112 | pad = RSA_PKCS1_PADDING; | ||
113 | |||
114 | while (argc >= 1) { | ||
115 | if (!strcmp(*argv, "-in")) { | ||
116 | if (--argc < 1) | ||
117 | badarg = 1; | ||
118 | else | ||
119 | infile = *(++argv); | ||
120 | } else if (!strcmp(*argv, "-out")) { | ||
121 | if (--argc < 1) | ||
122 | badarg = 1; | ||
123 | else | ||
124 | outfile = *(++argv); | ||
125 | } else if (!strcmp(*argv, "-inkey")) { | ||
126 | if (--argc < 1) | ||
127 | badarg = 1; | ||
128 | else | ||
129 | keyfile = *(++argv); | ||
130 | } else if (!strcmp(*argv, "-passin")) { | ||
131 | if (--argc < 1) | ||
132 | badarg = 1; | ||
133 | else | ||
134 | passargin = *(++argv); | ||
135 | } else if (strcmp(*argv, "-keyform") == 0) { | ||
136 | if (--argc < 1) | ||
137 | badarg = 1; | ||
138 | else | ||
139 | keyform = str2fmt(*(++argv)); | ||
140 | #ifndef OPENSSL_NO_ENGINE | ||
141 | } else if (!strcmp(*argv, "-engine")) { | ||
142 | if (--argc < 1) | ||
143 | badarg = 1; | ||
144 | else | ||
145 | engine = *(++argv); | ||
146 | #endif | ||
147 | } else if (!strcmp(*argv, "-pubin")) { | ||
148 | key_type = KEY_PUBKEY; | ||
149 | } else if (!strcmp(*argv, "-certin")) { | ||
150 | key_type = KEY_CERT; | ||
151 | } else if (!strcmp(*argv, "-asn1parse")) | ||
152 | asn1parse = 1; | ||
153 | else if (!strcmp(*argv, "-hexdump")) | ||
154 | hexdump = 1; | ||
155 | else if (!strcmp(*argv, "-raw")) | ||
156 | pad = RSA_NO_PADDING; | ||
157 | else if (!strcmp(*argv, "-oaep")) | ||
158 | pad = RSA_PKCS1_OAEP_PADDING; | ||
159 | else if (!strcmp(*argv, "-ssl")) | ||
160 | pad = RSA_SSLV23_PADDING; | ||
161 | else if (!strcmp(*argv, "-pkcs")) | ||
162 | pad = RSA_PKCS1_PADDING; | ||
163 | else if (!strcmp(*argv, "-x931")) | ||
164 | pad = RSA_X931_PADDING; | ||
165 | else if (!strcmp(*argv, "-sign")) { | ||
166 | rsa_mode = RSA_SIGN; | ||
167 | need_priv = 1; | ||
168 | } else if (!strcmp(*argv, "-verify")) | ||
169 | rsa_mode = RSA_VERIFY; | ||
170 | else if (!strcmp(*argv, "-rev")) | ||
171 | rev = 1; | ||
172 | else if (!strcmp(*argv, "-encrypt")) | ||
173 | rsa_mode = RSA_ENCRYPT; | ||
174 | else if (!strcmp(*argv, "-decrypt")) { | ||
175 | rsa_mode = RSA_DECRYPT; | ||
176 | need_priv = 1; | ||
177 | } else | ||
178 | badarg = 1; | ||
179 | if (badarg) { | ||
180 | usage(); | ||
181 | goto end; | ||
182 | } | ||
183 | argc--; | ||
184 | argv++; | ||
185 | } | ||
186 | |||
187 | if (need_priv && (key_type != KEY_PRIVKEY)) { | ||
188 | BIO_printf(bio_err, "A private key is needed for this operation\n"); | ||
189 | goto end; | ||
190 | } | ||
191 | #ifndef OPENSSL_NO_ENGINE | ||
192 | e = setup_engine(bio_err, engine, 0); | ||
193 | #endif | ||
194 | if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { | ||
195 | BIO_printf(bio_err, "Error getting password\n"); | ||
196 | goto end; | ||
197 | } | ||
198 | |||
199 | switch (key_type) { | ||
200 | case KEY_PRIVKEY: | ||
201 | pkey = load_key(bio_err, keyfile, keyform, 0, | ||
202 | passin, e, "Private Key"); | ||
203 | break; | ||
204 | |||
205 | case KEY_PUBKEY: | ||
206 | pkey = load_pubkey(bio_err, keyfile, keyform, 0, | ||
207 | NULL, e, "Public Key"); | ||
208 | break; | ||
209 | |||
210 | case KEY_CERT: | ||
211 | x = load_cert(bio_err, keyfile, keyform, | ||
212 | NULL, e, "Certificate"); | ||
213 | if (x) { | ||
214 | pkey = X509_get_pubkey(x); | ||
215 | X509_free(x); | ||
216 | } | ||
217 | break; | ||
218 | } | ||
219 | |||
220 | if (!pkey) { | ||
221 | return 1; | ||
222 | } | ||
223 | rsa = EVP_PKEY_get1_RSA(pkey); | ||
224 | EVP_PKEY_free(pkey); | ||
225 | |||
226 | if (!rsa) { | ||
227 | BIO_printf(bio_err, "Error getting RSA key\n"); | ||
228 | ERR_print_errors(bio_err); | ||
229 | goto end; | ||
230 | } | ||
231 | if (infile) { | ||
232 | if (!(in = BIO_new_file(infile, "rb"))) { | ||
233 | BIO_printf(bio_err, "Error Reading Input File\n"); | ||
234 | ERR_print_errors(bio_err); | ||
235 | goto end; | ||
236 | } | ||
237 | } else | ||
238 | in = BIO_new_fp(stdin, BIO_NOCLOSE); | ||
239 | |||
240 | if (outfile) { | ||
241 | if (!(out = BIO_new_file(outfile, "wb"))) { | ||
242 | BIO_printf(bio_err, "Error Reading Output File\n"); | ||
243 | ERR_print_errors(bio_err); | ||
244 | goto end; | ||
245 | } | ||
246 | } else { | ||
247 | out = BIO_new_fp(stdout, BIO_NOCLOSE); | ||
248 | } | ||
249 | |||
250 | keysize = RSA_size(rsa); | ||
251 | |||
252 | rsa_in = reallocarray(NULL, keysize, 2); | ||
253 | rsa_out = malloc(keysize); | ||
254 | |||
255 | /* Read the input data */ | ||
256 | rsa_inlen = BIO_read(in, rsa_in, keysize * 2); | ||
257 | if (rsa_inlen <= 0) { | ||
258 | BIO_printf(bio_err, "Error reading input Data\n"); | ||
259 | exit(1); | ||
260 | } | ||
261 | if (rev) { | ||
262 | int i; | ||
263 | unsigned char ctmp; | ||
264 | for (i = 0; i < rsa_inlen / 2; i++) { | ||
265 | ctmp = rsa_in[i]; | ||
266 | rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; | ||
267 | rsa_in[rsa_inlen - 1 - i] = ctmp; | ||
268 | } | ||
269 | } | ||
270 | switch (rsa_mode) { | ||
271 | |||
272 | case RSA_VERIFY: | ||
273 | rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); | ||
274 | break; | ||
275 | |||
276 | case RSA_SIGN: | ||
277 | rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); | ||
278 | break; | ||
279 | |||
280 | case RSA_ENCRYPT: | ||
281 | rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); | ||
282 | break; | ||
283 | |||
284 | case RSA_DECRYPT: | ||
285 | rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); | ||
286 | break; | ||
287 | |||
288 | } | ||
289 | |||
290 | if (rsa_outlen <= 0) { | ||
291 | BIO_printf(bio_err, "RSA operation error\n"); | ||
292 | ERR_print_errors(bio_err); | ||
293 | goto end; | ||
294 | } | ||
295 | ret = 0; | ||
296 | if (asn1parse) { | ||
297 | if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { | ||
298 | ERR_print_errors(bio_err); | ||
299 | } | ||
300 | } else if (hexdump) | ||
301 | BIO_dump(out, (char *) rsa_out, rsa_outlen); | ||
302 | else | ||
303 | BIO_write(out, rsa_out, rsa_outlen); | ||
304 | |||
305 | end: | ||
306 | RSA_free(rsa); | ||
307 | BIO_free(in); | ||
308 | BIO_free_all(out); | ||
309 | free(rsa_in); | ||
310 | free(rsa_out); | ||
311 | free(passin); | ||
312 | |||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | static void | ||
317 | usage() | ||
318 | { | ||
319 | BIO_printf(bio_err, "Usage: rsautl [options]\n"); | ||
320 | BIO_printf(bio_err, "-in file input file\n"); | ||
321 | BIO_printf(bio_err, "-out file output file\n"); | ||
322 | BIO_printf(bio_err, "-inkey file input key\n"); | ||
323 | BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); | ||
324 | BIO_printf(bio_err, "-pubin input is an RSA public\n"); | ||
325 | BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n"); | ||
326 | BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); | ||
327 | BIO_printf(bio_err, "-raw use no padding\n"); | ||
328 | BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n"); | ||
329 | BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); | ||
330 | BIO_printf(bio_err, "-sign sign with private key\n"); | ||
331 | BIO_printf(bio_err, "-verify verify with public key\n"); | ||
332 | BIO_printf(bio_err, "-encrypt encrypt with public key\n"); | ||
333 | BIO_printf(bio_err, "-decrypt decrypt with private key\n"); | ||
334 | BIO_printf(bio_err, "-hexdump hex dump output\n"); | ||
335 | #ifndef OPENSSL_NO_ENGINE | ||
336 | BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); | ||
337 | BIO_printf(bio_err, "-passin arg pass phrase source\n"); | ||
338 | #endif | ||
339 | |||
340 | } | ||
341 | |||