]> git.ipfire.org Git - thirdparty/openssl.git/blob - apps/rsautl.c
Use OSSL_STORE for load_{,pub}key() and load_cert() in apps/lib/apps.c
[thirdparty/openssl.git] / apps / rsautl.c
1 /*
2 * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
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
8 */
9
10 /* We need to use the deprecated RSA low level calls */
11 #define OPENSSL_SUPPRESS_DEPRECATED
12
13 #include <openssl/opensslconf.h>
14
15 #include "apps.h"
16 #include "progs.h"
17 #include <string.h>
18 #include <openssl/err.h>
19 #include <openssl/pem.h>
20 #include <openssl/rsa.h>
21
22 #define RSA_SIGN 1
23 #define RSA_VERIFY 2
24 #define RSA_ENCRYPT 3
25 #define RSA_DECRYPT 4
26
27 #define KEY_PRIVKEY 1
28 #define KEY_PUBKEY 2
29 #define KEY_CERT 3
30
31 typedef enum OPTION_choice {
32 OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
33 OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP,
34 OPT_RSA_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931,
35 OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
36 OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM,
37 OPT_R_ENUM, OPT_PROV_ENUM
38 } OPTION_CHOICE;
39
40 const OPTIONS rsautl_options[] = {
41 OPT_SECTION("General"),
42 {"help", OPT_HELP, '-', "Display this summary"},
43 {"sign", OPT_SIGN, '-', "Sign with private key"},
44 {"verify", OPT_VERIFY, '-', "Verify with public key"},
45 {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"},
46 {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"},
47 #ifndef OPENSSL_NO_ENGINE
48 {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
49 #endif
50
51 OPT_SECTION("Input"),
52 {"in", OPT_IN, '<', "Input file"},
53 {"inkey", OPT_INKEY, 's', "Input key"},
54 {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"},
55 {"pubin", OPT_PUBIN, '-', "Input is an RSA public"},
56 {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"},
57 {"rev", OPT_REV, '-', "Reverse the order of the input buffer"},
58 {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
59
60 OPT_SECTION("Output"),
61 {"out", OPT_OUT, '>', "Output file"},
62 {"ssl", OPT_SSL, '-', "Use SSL v2 padding"},
63 {"raw", OPT_RSA_RAW, '-', "Use no padding"},
64 {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"},
65 {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"},
66 {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"},
67 {"asn1parse", OPT_ASN1PARSE, '-',
68 "Run output through asn1parse; useful with -verify"},
69 {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"},
70
71 OPT_R_OPTIONS,
72 OPT_PROV_OPTIONS,
73 {NULL}
74 };
75
76 int rsautl_main(int argc, char **argv)
77 {
78 BIO *in = NULL, *out = NULL;
79 ENGINE *e = NULL;
80 EVP_PKEY *pkey = NULL;
81 RSA *rsa = NULL;
82 X509 *x;
83 char *infile = NULL, *outfile = NULL, *keyfile = NULL;
84 char *passinarg = NULL, *passin = NULL, *prog;
85 char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
86 unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING;
87 int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1;
88 int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0;
89 OPTION_CHOICE o;
90
91 prog = opt_init(argc, argv, rsautl_options);
92 while ((o = opt_next()) != OPT_EOF) {
93 switch (o) {
94 case OPT_EOF:
95 case OPT_ERR:
96 opthelp:
97 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
98 goto end;
99 case OPT_HELP:
100 opt_help(rsautl_options);
101 ret = 0;
102 goto end;
103 case OPT_KEYFORM:
104 if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
105 goto opthelp;
106 break;
107 case OPT_IN:
108 infile = opt_arg();
109 break;
110 case OPT_OUT:
111 outfile = opt_arg();
112 break;
113 case OPT_ENGINE:
114 e = setup_engine(opt_arg(), 0);
115 break;
116 case OPT_ASN1PARSE:
117 asn1parse = 1;
118 break;
119 case OPT_HEXDUMP:
120 hexdump = 1;
121 break;
122 case OPT_RSA_RAW:
123 pad = RSA_NO_PADDING;
124 break;
125 case OPT_OAEP:
126 pad = RSA_PKCS1_OAEP_PADDING;
127 break;
128 case OPT_SSL:
129 pad = RSA_SSLV23_PADDING;
130 break;
131 case OPT_PKCS:
132 pad = RSA_PKCS1_PADDING;
133 break;
134 case OPT_X931:
135 pad = RSA_X931_PADDING;
136 break;
137 case OPT_SIGN:
138 rsa_mode = RSA_SIGN;
139 need_priv = 1;
140 break;
141 case OPT_VERIFY:
142 rsa_mode = RSA_VERIFY;
143 break;
144 case OPT_REV:
145 rev = 1;
146 break;
147 case OPT_ENCRYPT:
148 rsa_mode = RSA_ENCRYPT;
149 break;
150 case OPT_DECRYPT:
151 rsa_mode = RSA_DECRYPT;
152 need_priv = 1;
153 break;
154 case OPT_PUBIN:
155 key_type = KEY_PUBKEY;
156 break;
157 case OPT_CERTIN:
158 key_type = KEY_CERT;
159 break;
160 case OPT_INKEY:
161 keyfile = opt_arg();
162 break;
163 case OPT_PASSIN:
164 passinarg = opt_arg();
165 break;
166 case OPT_R_CASES:
167 if (!opt_rand(o))
168 goto end;
169 break;
170 case OPT_PROV_CASES:
171 if (!opt_provider(o))
172 goto end;
173 break;
174 }
175 }
176 argc = opt_num_rest();
177 if (argc != 0)
178 goto opthelp;
179
180 if (need_priv && (key_type != KEY_PRIVKEY)) {
181 BIO_printf(bio_err, "A private key is needed for this operation\n");
182 goto end;
183 }
184
185 if (!app_passwd(passinarg, NULL, &passin, NULL)) {
186 BIO_printf(bio_err, "Error getting password\n");
187 goto end;
188 }
189
190 switch (key_type) {
191 case KEY_PRIVKEY:
192 pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key");
193 break;
194
195 case KEY_PUBKEY:
196 pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key");
197 break;
198
199 case KEY_CERT:
200 x = load_cert(keyfile, FORMAT_UNDEF, "Certificate");
201 if (x) {
202 pkey = X509_get_pubkey(x);
203 X509_free(x);
204 }
205 break;
206 }
207
208 if (pkey == NULL)
209 return 1;
210
211 rsa = EVP_PKEY_get1_RSA(pkey);
212 EVP_PKEY_free(pkey);
213
214 if (rsa == NULL) {
215 BIO_printf(bio_err, "Error getting RSA key\n");
216 ERR_print_errors(bio_err);
217 goto end;
218 }
219
220 in = bio_open_default(infile, 'r', FORMAT_BINARY);
221 if (in == NULL)
222 goto end;
223 out = bio_open_default(outfile, 'w', FORMAT_BINARY);
224 if (out == NULL)
225 goto end;
226
227 keysize = RSA_size(rsa);
228
229 rsa_in = app_malloc(keysize * 2, "hold rsa key");
230 rsa_out = app_malloc(keysize, "output rsa key");
231
232 /* Read the input data */
233 rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
234 if (rsa_inlen < 0) {
235 BIO_printf(bio_err, "Error reading input Data\n");
236 goto end;
237 }
238 if (rev) {
239 int i;
240 unsigned char ctmp;
241 for (i = 0; i < rsa_inlen / 2; i++) {
242 ctmp = rsa_in[i];
243 rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
244 rsa_in[rsa_inlen - 1 - i] = ctmp;
245 }
246 }
247 switch (rsa_mode) {
248
249 case RSA_VERIFY:
250 rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
251 break;
252
253 case RSA_SIGN:
254 rsa_outlen =
255 RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
256 break;
257
258 case RSA_ENCRYPT:
259 rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
260 break;
261
262 case RSA_DECRYPT:
263 rsa_outlen =
264 RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
265 break;
266 }
267
268 if (rsa_outlen < 0) {
269 BIO_printf(bio_err, "RSA operation error\n");
270 ERR_print_errors(bio_err);
271 goto end;
272 }
273 ret = 0;
274 if (asn1parse) {
275 if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
276 ERR_print_errors(bio_err);
277 }
278 } else if (hexdump) {
279 BIO_dump(out, (char *)rsa_out, rsa_outlen);
280 } else {
281 BIO_write(out, rsa_out, rsa_outlen);
282 }
283 end:
284 RSA_free(rsa);
285 release_engine(e);
286 BIO_free(in);
287 BIO_free_all(out);
288 OPENSSL_free(rsa_in);
289 OPENSSL_free(rsa_out);
290 OPENSSL_free(passin);
291 return ret;
292 }