Annotation of src/usr.bin/openssl/rsautl.c, Revision 1.6
1.6 ! jsing 1: /* $OpenBSD: rsautl.c,v 1.5 2015/07/19 03:14:09 doug Exp $ */
1.1 jsing 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
82: rsautl_main(int argc, char **argv)
83: {
84: ENGINE *e = NULL;
85: BIO *in = NULL, *out = NULL;
86: char *infile = NULL, *outfile = NULL;
87: #ifndef OPENSSL_NO_ENGINE
88: char *engine = NULL;
89: #endif
90: char *keyfile = NULL;
91: char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
92: int keyform = FORMAT_PEM;
93: char need_priv = 0, badarg = 0, rev = 0;
94: char hexdump = 0, asn1parse = 0;
95: X509 *x;
96: EVP_PKEY *pkey = NULL;
97: RSA *rsa = NULL;
98: unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
99: char *passargin = NULL, *passin = NULL;
100: int rsa_inlen, rsa_outlen = 0;
101: int keysize;
102:
103: int ret = 1;
104:
105: argc--;
106: argv++;
107:
108: pad = RSA_PKCS1_PADDING;
109:
110: while (argc >= 1) {
111: if (!strcmp(*argv, "-in")) {
112: if (--argc < 1)
113: badarg = 1;
114: else
115: infile = *(++argv);
116: } else if (!strcmp(*argv, "-out")) {
117: if (--argc < 1)
118: badarg = 1;
119: else
120: outfile = *(++argv);
121: } else if (!strcmp(*argv, "-inkey")) {
122: if (--argc < 1)
123: badarg = 1;
124: else
125: keyfile = *(++argv);
126: } else if (!strcmp(*argv, "-passin")) {
127: if (--argc < 1)
128: badarg = 1;
129: else
130: passargin = *(++argv);
131: } else if (strcmp(*argv, "-keyform") == 0) {
132: if (--argc < 1)
133: badarg = 1;
134: else
135: keyform = str2fmt(*(++argv));
136: #ifndef OPENSSL_NO_ENGINE
137: } else if (!strcmp(*argv, "-engine")) {
138: if (--argc < 1)
139: badarg = 1;
140: else
141: engine = *(++argv);
142: #endif
143: } else if (!strcmp(*argv, "-pubin")) {
144: key_type = KEY_PUBKEY;
145: } else if (!strcmp(*argv, "-certin")) {
146: key_type = KEY_CERT;
147: } else if (!strcmp(*argv, "-asn1parse"))
148: asn1parse = 1;
149: else if (!strcmp(*argv, "-hexdump"))
150: hexdump = 1;
151: else if (!strcmp(*argv, "-raw"))
152: pad = RSA_NO_PADDING;
153: else if (!strcmp(*argv, "-oaep"))
154: pad = RSA_PKCS1_OAEP_PADDING;
155: else if (!strcmp(*argv, "-ssl"))
156: pad = RSA_SSLV23_PADDING;
157: else if (!strcmp(*argv, "-pkcs"))
158: pad = RSA_PKCS1_PADDING;
159: else if (!strcmp(*argv, "-x931"))
160: pad = RSA_X931_PADDING;
161: else if (!strcmp(*argv, "-sign")) {
162: rsa_mode = RSA_SIGN;
163: need_priv = 1;
164: } else if (!strcmp(*argv, "-verify"))
165: rsa_mode = RSA_VERIFY;
166: else if (!strcmp(*argv, "-rev"))
167: rev = 1;
168: else if (!strcmp(*argv, "-encrypt"))
169: rsa_mode = RSA_ENCRYPT;
170: else if (!strcmp(*argv, "-decrypt")) {
171: rsa_mode = RSA_DECRYPT;
172: need_priv = 1;
173: } else
174: badarg = 1;
175: if (badarg) {
176: usage();
177: goto end;
178: }
179: argc--;
180: argv++;
181: }
182:
183: if (need_priv && (key_type != KEY_PRIVKEY)) {
184: BIO_printf(bio_err, "A private key is needed for this operation\n");
185: goto end;
186: }
187: #ifndef OPENSSL_NO_ENGINE
188: e = setup_engine(bio_err, engine, 0);
189: #endif
190: if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
191: BIO_printf(bio_err, "Error getting password\n");
192: goto end;
193: }
194:
195: switch (key_type) {
196: case KEY_PRIVKEY:
197: pkey = load_key(bio_err, keyfile, keyform, 0,
198: passin, e, "Private Key");
199: break;
200:
201: case KEY_PUBKEY:
202: pkey = load_pubkey(bio_err, keyfile, keyform, 0,
203: NULL, e, "Public Key");
204: break;
205:
206: case KEY_CERT:
207: x = load_cert(bio_err, keyfile, keyform,
208: NULL, e, "Certificate");
209: if (x) {
210: pkey = X509_get_pubkey(x);
211: X509_free(x);
212: }
213: break;
214: }
215:
1.5 doug 216: if (!pkey)
217: goto end;
218:
1.1 jsing 219: rsa = EVP_PKEY_get1_RSA(pkey);
220: EVP_PKEY_free(pkey);
221:
222: if (!rsa) {
223: BIO_printf(bio_err, "Error getting RSA key\n");
224: ERR_print_errors(bio_err);
225: goto end;
226: }
227: if (infile) {
228: if (!(in = BIO_new_file(infile, "rb"))) {
229: BIO_printf(bio_err, "Error Reading Input File\n");
230: ERR_print_errors(bio_err);
231: goto end;
232: }
233: } else
234: in = BIO_new_fp(stdin, BIO_NOCLOSE);
235:
236: if (outfile) {
237: if (!(out = BIO_new_file(outfile, "wb"))) {
238: BIO_printf(bio_err, "Error Reading Output File\n");
239: ERR_print_errors(bio_err);
240: goto end;
241: }
242: } else {
243: out = BIO_new_fp(stdout, BIO_NOCLOSE);
244: }
245:
246: keysize = RSA_size(rsa);
247:
248: rsa_in = reallocarray(NULL, keysize, 2);
1.4 lteo 249: if (rsa_in == NULL) {
250: BIO_printf(bio_err, "Error allocating memory for input data\n");
251: exit(1);
252: }
1.1 jsing 253: rsa_out = malloc(keysize);
1.4 lteo 254: if (rsa_out == NULL) {
255: BIO_printf(bio_err, "Error allocating memory for output data\n");
256: exit(1);
257: }
1.1 jsing 258:
259: /* Read the input data */
260: rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
261: if (rsa_inlen <= 0) {
262: BIO_printf(bio_err, "Error reading input Data\n");
263: exit(1);
264: }
265: if (rev) {
266: int i;
267: unsigned char ctmp;
268: for (i = 0; i < rsa_inlen / 2; i++) {
269: ctmp = rsa_in[i];
270: rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
271: rsa_in[rsa_inlen - 1 - i] = ctmp;
272: }
273: }
274: switch (rsa_mode) {
275:
276: case RSA_VERIFY:
277: rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
278: break;
279:
280: case RSA_SIGN:
281: rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
282: break;
283:
284: case RSA_ENCRYPT:
285: rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
286: break;
287:
288: case RSA_DECRYPT:
289: rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
290: break;
291:
292: }
293:
294: if (rsa_outlen <= 0) {
295: BIO_printf(bio_err, "RSA operation error\n");
296: ERR_print_errors(bio_err);
297: goto end;
298: }
299: ret = 0;
300: if (asn1parse) {
301: if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
302: ERR_print_errors(bio_err);
303: }
304: } else if (hexdump)
305: BIO_dump(out, (char *) rsa_out, rsa_outlen);
306: else
307: BIO_write(out, rsa_out, rsa_outlen);
308:
309: end:
310: RSA_free(rsa);
311: BIO_free(in);
312: BIO_free_all(out);
313: free(rsa_in);
314: free(rsa_out);
315: free(passin);
316:
317: return ret;
318: }
319:
320: static void
321: usage()
322: {
323: BIO_printf(bio_err, "Usage: rsautl [options]\n");
324: BIO_printf(bio_err, "-in file input file\n");
325: BIO_printf(bio_err, "-out file output file\n");
326: BIO_printf(bio_err, "-inkey file input key\n");
327: BIO_printf(bio_err, "-keyform arg private key format - default PEM\n");
328: BIO_printf(bio_err, "-pubin input is an RSA public\n");
329: BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n");
330: BIO_printf(bio_err, "-ssl use SSL v2 padding\n");
331: BIO_printf(bio_err, "-raw use no padding\n");
332: BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n");
333: BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n");
334: BIO_printf(bio_err, "-sign sign with private key\n");
335: BIO_printf(bio_err, "-verify verify with public key\n");
336: BIO_printf(bio_err, "-encrypt encrypt with public key\n");
337: BIO_printf(bio_err, "-decrypt decrypt with private key\n");
338: BIO_printf(bio_err, "-hexdump hex dump output\n");
339: #ifndef OPENSSL_NO_ENGINE
340: BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
341: BIO_printf(bio_err, "-passin arg pass phrase source\n");
342: #endif
343:
344: }
345: