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