1ddd58736SKris Kennaway /* rsautl.c */ 2ddd58736SKris Kennaway /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3ddd58736SKris Kennaway * project 2000. 4ddd58736SKris Kennaway */ 5ddd58736SKris Kennaway /* ==================================================================== 6ddd58736SKris Kennaway * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7ddd58736SKris Kennaway * 8ddd58736SKris Kennaway * Redistribution and use in source and binary forms, with or without 9ddd58736SKris Kennaway * modification, are permitted provided that the following conditions 10ddd58736SKris Kennaway * are met: 11ddd58736SKris Kennaway * 12ddd58736SKris Kennaway * 1. Redistributions of source code must retain the above copyright 13ddd58736SKris Kennaway * notice, this list of conditions and the following disclaimer. 14ddd58736SKris Kennaway * 15ddd58736SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 16ddd58736SKris Kennaway * notice, this list of conditions and the following disclaimer in 17ddd58736SKris Kennaway * the documentation and/or other materials provided with the 18ddd58736SKris Kennaway * distribution. 19ddd58736SKris Kennaway * 20ddd58736SKris Kennaway * 3. All advertising materials mentioning features or use of this 21ddd58736SKris Kennaway * software must display the following acknowledgment: 22ddd58736SKris Kennaway * "This product includes software developed by the OpenSSL Project 23ddd58736SKris Kennaway * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24ddd58736SKris Kennaway * 25ddd58736SKris Kennaway * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26ddd58736SKris Kennaway * endorse or promote products derived from this software without 27ddd58736SKris Kennaway * prior written permission. For written permission, please contact 28ddd58736SKris Kennaway * licensing@OpenSSL.org. 29ddd58736SKris Kennaway * 30ddd58736SKris Kennaway * 5. Products derived from this software may not be called "OpenSSL" 31ddd58736SKris Kennaway * nor may "OpenSSL" appear in their names without prior written 32ddd58736SKris Kennaway * permission of the OpenSSL Project. 33ddd58736SKris Kennaway * 34ddd58736SKris Kennaway * 6. Redistributions of any form whatsoever must retain the following 35ddd58736SKris Kennaway * acknowledgment: 36ddd58736SKris Kennaway * "This product includes software developed by the OpenSSL Project 37ddd58736SKris Kennaway * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38ddd58736SKris Kennaway * 39ddd58736SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40ddd58736SKris Kennaway * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41ddd58736SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42ddd58736SKris Kennaway * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43ddd58736SKris Kennaway * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44ddd58736SKris Kennaway * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45ddd58736SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46ddd58736SKris Kennaway * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47ddd58736SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48ddd58736SKris Kennaway * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49ddd58736SKris Kennaway * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50ddd58736SKris Kennaway * OF THE POSSIBILITY OF SUCH DAMAGE. 51ddd58736SKris Kennaway * ==================================================================== 52ddd58736SKris Kennaway * 53ddd58736SKris Kennaway * This product includes cryptographic software written by Eric Young 54ddd58736SKris Kennaway * (eay@cryptsoft.com). This product includes software written by Tim 55ddd58736SKris Kennaway * Hudson (tjh@cryptsoft.com). 56ddd58736SKris Kennaway * 57ddd58736SKris Kennaway */ 58de7cdddaSKris Kennaway 595c87c606SMark Murray #ifndef OPENSSL_NO_RSA 60de7cdddaSKris Kennaway 61ddd58736SKris Kennaway #include "apps.h" 62ddd58736SKris Kennaway #include <string.h> 63ddd58736SKris Kennaway #include <openssl/err.h> 64ddd58736SKris Kennaway #include <openssl/pem.h> 65ddd58736SKris Kennaway 66ddd58736SKris Kennaway #define RSA_SIGN 1 67ddd58736SKris Kennaway #define RSA_VERIFY 2 68ddd58736SKris Kennaway #define RSA_ENCRYPT 3 69ddd58736SKris Kennaway #define RSA_DECRYPT 4 70ddd58736SKris Kennaway 71ddd58736SKris Kennaway #define KEY_PRIVKEY 1 72ddd58736SKris Kennaway #define KEY_PUBKEY 2 73ddd58736SKris Kennaway #define KEY_CERT 3 74ddd58736SKris Kennaway 75ddd58736SKris Kennaway static void usage(void); 76ddd58736SKris Kennaway 77ddd58736SKris Kennaway #undef PROG 78ddd58736SKris Kennaway 79ddd58736SKris Kennaway #define PROG rsautl_main 80ddd58736SKris Kennaway 81ddd58736SKris Kennaway int MAIN(int argc, char **); 82ddd58736SKris Kennaway 83ddd58736SKris Kennaway int MAIN(int argc, char **argv) 84ddd58736SKris Kennaway { 855c87c606SMark Murray ENGINE *e = NULL; 86ddd58736SKris Kennaway BIO *in = NULL, *out = NULL; 87ddd58736SKris Kennaway char *infile = NULL, *outfile = NULL; 88fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE 895c87c606SMark Murray char *engine = NULL; 90fceca8a3SJacques Vidrine #endif 91ddd58736SKris Kennaway char *keyfile = NULL; 92ddd58736SKris Kennaway char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; 93ddd58736SKris Kennaway int keyform = FORMAT_PEM; 94ddd58736SKris Kennaway char need_priv = 0, badarg = 0, rev = 0; 95ddd58736SKris Kennaway char hexdump = 0, asn1parse = 0; 96ddd58736SKris Kennaway X509 *x; 97ddd58736SKris Kennaway EVP_PKEY *pkey = NULL; 98ddd58736SKris Kennaway RSA *rsa = NULL; 99ddd58736SKris Kennaway unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; 100ced566fdSJacques Vidrine char *passargin = NULL, *passin = NULL; 101ddd58736SKris Kennaway int rsa_inlen, rsa_outlen = 0; 102ddd58736SKris Kennaway int keysize; 103ddd58736SKris Kennaway 104ddd58736SKris Kennaway int ret = 1; 105ddd58736SKris Kennaway 106ddd58736SKris Kennaway argc--; 107ddd58736SKris Kennaway argv++; 108ddd58736SKris Kennaway 109ddd58736SKris Kennaway if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 1105c87c606SMark Murray 1115c87c606SMark Murray if (!load_config(bio_err, NULL)) 1125c87c606SMark Murray goto end; 113ddd58736SKris Kennaway ERR_load_crypto_strings(); 114ddd58736SKris Kennaway OpenSSL_add_all_algorithms(); 115ddd58736SKris Kennaway pad = RSA_PKCS1_PADDING; 116ddd58736SKris Kennaway 117ddd58736SKris Kennaway while(argc >= 1) 118ddd58736SKris Kennaway { 119ddd58736SKris Kennaway if (!strcmp(*argv,"-in")) { 120ddd58736SKris Kennaway if (--argc < 1) badarg = 1; 121ddd58736SKris Kennaway infile= *(++argv); 122ddd58736SKris Kennaway } else if (!strcmp(*argv,"-out")) { 123ddd58736SKris Kennaway if (--argc < 1) badarg = 1; 124ddd58736SKris Kennaway outfile= *(++argv); 125ddd58736SKris Kennaway } else if(!strcmp(*argv, "-inkey")) { 126ddd58736SKris Kennaway if (--argc < 1) badarg = 1; 127ddd58736SKris Kennaway keyfile = *(++argv); 128ced566fdSJacques Vidrine } else if (!strcmp(*argv,"-passin")) { 129ced566fdSJacques Vidrine if (--argc < 1) badarg = 1; 130ced566fdSJacques Vidrine passargin= *(++argv); 1315c87c606SMark Murray } else if (strcmp(*argv,"-keyform") == 0) { 1325c87c606SMark Murray if (--argc < 1) badarg = 1; 1335c87c606SMark Murray keyform=str2fmt(*(++argv)); 134fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE 1355c87c606SMark Murray } else if(!strcmp(*argv, "-engine")) { 1365c87c606SMark Murray if (--argc < 1) badarg = 1; 1375c87c606SMark Murray engine = *(++argv); 138fceca8a3SJacques Vidrine #endif 139ddd58736SKris Kennaway } else if(!strcmp(*argv, "-pubin")) { 140ddd58736SKris Kennaway key_type = KEY_PUBKEY; 141ddd58736SKris Kennaway } else if(!strcmp(*argv, "-certin")) { 142ddd58736SKris Kennaway key_type = KEY_CERT; 143ddd58736SKris Kennaway } 144ddd58736SKris Kennaway else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1; 145ddd58736SKris Kennaway else if(!strcmp(*argv, "-hexdump")) hexdump = 1; 146ddd58736SKris Kennaway else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; 147ddd58736SKris Kennaway else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; 148ddd58736SKris Kennaway else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; 149ddd58736SKris Kennaway else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; 150ddd58736SKris Kennaway else if(!strcmp(*argv, "-sign")) { 151ddd58736SKris Kennaway rsa_mode = RSA_SIGN; 152ddd58736SKris Kennaway need_priv = 1; 153ddd58736SKris Kennaway } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; 154ddd58736SKris Kennaway else if(!strcmp(*argv, "-rev")) rev = 1; 155ddd58736SKris Kennaway else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; 156ddd58736SKris Kennaway else if(!strcmp(*argv, "-decrypt")) { 157ddd58736SKris Kennaway rsa_mode = RSA_DECRYPT; 158ddd58736SKris Kennaway need_priv = 1; 159ddd58736SKris Kennaway } else badarg = 1; 160ddd58736SKris Kennaway if(badarg) { 161ddd58736SKris Kennaway usage(); 162ddd58736SKris Kennaway goto end; 163ddd58736SKris Kennaway } 164ddd58736SKris Kennaway argc--; 165ddd58736SKris Kennaway argv++; 166ddd58736SKris Kennaway } 167ddd58736SKris Kennaway 168ddd58736SKris Kennaway if(need_priv && (key_type != KEY_PRIVKEY)) { 169ddd58736SKris Kennaway BIO_printf(bio_err, "A private key is needed for this operation\n"); 170ddd58736SKris Kennaway goto end; 171ddd58736SKris Kennaway } 172ddd58736SKris Kennaway 173fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE 1745c87c606SMark Murray e = setup_engine(bio_err, engine, 0); 175fceca8a3SJacques Vidrine #endif 176ced566fdSJacques Vidrine if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 177ced566fdSJacques Vidrine BIO_printf(bio_err, "Error getting password\n"); 178ced566fdSJacques Vidrine goto end; 179ced566fdSJacques Vidrine } 1805c87c606SMark Murray 181ddd58736SKris Kennaway /* FIXME: seed PRNG only if needed */ 182ddd58736SKris Kennaway app_RAND_load_file(NULL, bio_err, 0); 183ddd58736SKris Kennaway 184ddd58736SKris Kennaway switch(key_type) { 185ddd58736SKris Kennaway case KEY_PRIVKEY: 1865c87c606SMark Murray pkey = load_key(bio_err, keyfile, keyform, 0, 187ced566fdSJacques Vidrine passin, e, "Private Key"); 188ddd58736SKris Kennaway break; 189ddd58736SKris Kennaway 190ddd58736SKris Kennaway case KEY_PUBKEY: 1915c87c606SMark Murray pkey = load_pubkey(bio_err, keyfile, keyform, 0, 1925c87c606SMark Murray NULL, e, "Public Key"); 193ddd58736SKris Kennaway break; 194ddd58736SKris Kennaway 195ddd58736SKris Kennaway case KEY_CERT: 1965c87c606SMark Murray x = load_cert(bio_err, keyfile, keyform, 1975c87c606SMark Murray NULL, e, "Certificate"); 198ddd58736SKris Kennaway if(x) { 199ddd58736SKris Kennaway pkey = X509_get_pubkey(x); 200ddd58736SKris Kennaway X509_free(x); 201ddd58736SKris Kennaway } 202ddd58736SKris Kennaway break; 203ddd58736SKris Kennaway } 204ddd58736SKris Kennaway 205ddd58736SKris Kennaway if(!pkey) { 206ddd58736SKris Kennaway return 1; 207ddd58736SKris Kennaway } 208ddd58736SKris Kennaway 209ddd58736SKris Kennaway rsa = EVP_PKEY_get1_RSA(pkey); 210ddd58736SKris Kennaway EVP_PKEY_free(pkey); 211ddd58736SKris Kennaway 212ddd58736SKris Kennaway if(!rsa) { 213ddd58736SKris Kennaway BIO_printf(bio_err, "Error getting RSA key\n"); 214ddd58736SKris Kennaway ERR_print_errors(bio_err); 215ddd58736SKris Kennaway goto end; 216ddd58736SKris Kennaway } 217ddd58736SKris Kennaway 218ddd58736SKris Kennaway 219ddd58736SKris Kennaway if(infile) { 220ddd58736SKris Kennaway if(!(in = BIO_new_file(infile, "rb"))) { 221ddd58736SKris Kennaway BIO_printf(bio_err, "Error Reading Input File\n"); 222ddd58736SKris Kennaway ERR_print_errors(bio_err); 223ddd58736SKris Kennaway goto end; 224ddd58736SKris Kennaway } 225ddd58736SKris Kennaway } else in = BIO_new_fp(stdin, BIO_NOCLOSE); 226ddd58736SKris Kennaway 227ddd58736SKris Kennaway if(outfile) { 228ddd58736SKris Kennaway if(!(out = BIO_new_file(outfile, "wb"))) { 229ddd58736SKris Kennaway BIO_printf(bio_err, "Error Reading Output File\n"); 230ddd58736SKris Kennaway ERR_print_errors(bio_err); 231ddd58736SKris Kennaway goto end; 232ddd58736SKris Kennaway } 233ddd58736SKris Kennaway } else { 234ddd58736SKris Kennaway out = BIO_new_fp(stdout, BIO_NOCLOSE); 2355c87c606SMark Murray #ifdef OPENSSL_SYS_VMS 236ddd58736SKris Kennaway { 237ddd58736SKris Kennaway BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 238ddd58736SKris Kennaway out = BIO_push(tmpbio, out); 239ddd58736SKris Kennaway } 240ddd58736SKris Kennaway #endif 241ddd58736SKris Kennaway } 242ddd58736SKris Kennaway 243ddd58736SKris Kennaway keysize = RSA_size(rsa); 244ddd58736SKris Kennaway 245ddd58736SKris Kennaway rsa_in = OPENSSL_malloc(keysize * 2); 246ddd58736SKris Kennaway rsa_out = OPENSSL_malloc(keysize); 247ddd58736SKris Kennaway 248ddd58736SKris Kennaway /* Read the input data */ 249ddd58736SKris Kennaway rsa_inlen = BIO_read(in, rsa_in, keysize * 2); 250ddd58736SKris Kennaway if(rsa_inlen <= 0) { 251ddd58736SKris Kennaway BIO_printf(bio_err, "Error reading input Data\n"); 252ddd58736SKris Kennaway exit(1); 253ddd58736SKris Kennaway } 254ddd58736SKris Kennaway if(rev) { 255ddd58736SKris Kennaway int i; 256ddd58736SKris Kennaway unsigned char ctmp; 257ddd58736SKris Kennaway for(i = 0; i < rsa_inlen/2; i++) { 258ddd58736SKris Kennaway ctmp = rsa_in[i]; 259ddd58736SKris Kennaway rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; 260ddd58736SKris Kennaway rsa_in[rsa_inlen - 1 - i] = ctmp; 261ddd58736SKris Kennaway } 262ddd58736SKris Kennaway } 263ddd58736SKris Kennaway switch(rsa_mode) { 264ddd58736SKris Kennaway 265ddd58736SKris Kennaway case RSA_VERIFY: 266ddd58736SKris Kennaway rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 267ddd58736SKris Kennaway break; 268ddd58736SKris Kennaway 269ddd58736SKris Kennaway case RSA_SIGN: 270ddd58736SKris Kennaway rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 271ddd58736SKris Kennaway break; 272ddd58736SKris Kennaway 273ddd58736SKris Kennaway case RSA_ENCRYPT: 274ddd58736SKris Kennaway rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 275ddd58736SKris Kennaway break; 276ddd58736SKris Kennaway 277ddd58736SKris Kennaway case RSA_DECRYPT: 278ddd58736SKris Kennaway rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 279ddd58736SKris Kennaway break; 280ddd58736SKris Kennaway 281ddd58736SKris Kennaway } 282ddd58736SKris Kennaway 283ddd58736SKris Kennaway if(rsa_outlen <= 0) { 284ddd58736SKris Kennaway BIO_printf(bio_err, "RSA operation error\n"); 285ddd58736SKris Kennaway ERR_print_errors(bio_err); 286ddd58736SKris Kennaway goto end; 287ddd58736SKris Kennaway } 288ddd58736SKris Kennaway ret = 0; 289ddd58736SKris Kennaway if(asn1parse) { 290ddd58736SKris Kennaway if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { 291ddd58736SKris Kennaway ERR_print_errors(bio_err); 292ddd58736SKris Kennaway } 293ddd58736SKris Kennaway } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); 294ddd58736SKris Kennaway else BIO_write(out, rsa_out, rsa_outlen); 295ddd58736SKris Kennaway end: 296ddd58736SKris Kennaway RSA_free(rsa); 297ddd58736SKris Kennaway BIO_free(in); 298ddd58736SKris Kennaway BIO_free_all(out); 299ddd58736SKris Kennaway if(rsa_in) OPENSSL_free(rsa_in); 300ddd58736SKris Kennaway if(rsa_out) OPENSSL_free(rsa_out); 301ced566fdSJacques Vidrine if(passin) OPENSSL_free(passin); 302ddd58736SKris Kennaway return ret; 303ddd58736SKris Kennaway } 304ddd58736SKris Kennaway 305ddd58736SKris Kennaway static void usage() 306ddd58736SKris Kennaway { 307ddd58736SKris Kennaway BIO_printf(bio_err, "Usage: rsautl [options]\n"); 308ddd58736SKris Kennaway BIO_printf(bio_err, "-in file input file\n"); 309ddd58736SKris Kennaway BIO_printf(bio_err, "-out file output file\n"); 310ddd58736SKris Kennaway BIO_printf(bio_err, "-inkey file input key\n"); 3115c87c606SMark Murray BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); 312ddd58736SKris Kennaway BIO_printf(bio_err, "-pubin input is an RSA public\n"); 313ddd58736SKris Kennaway BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n"); 314ddd58736SKris Kennaway BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); 315ddd58736SKris Kennaway BIO_printf(bio_err, "-raw use no padding\n"); 316ddd58736SKris Kennaway BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n"); 317ddd58736SKris Kennaway BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); 318ddd58736SKris Kennaway BIO_printf(bio_err, "-sign sign with private key\n"); 319ddd58736SKris Kennaway BIO_printf(bio_err, "-verify verify with public key\n"); 320ddd58736SKris Kennaway BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 321ddd58736SKris Kennaway BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 322ddd58736SKris Kennaway BIO_printf(bio_err, "-hexdump hex dump output\n"); 323fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE 3245c87c606SMark Murray BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); 325ced566fdSJacques Vidrine BIO_printf (bio_err, "-passin arg pass phrase source\n"); 326fceca8a3SJacques Vidrine #endif 3275c87c606SMark Murray 328ddd58736SKris Kennaway } 329ddd58736SKris Kennaway 330de7cdddaSKris Kennaway #endif 331