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