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