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