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