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 59de7cdddaSKris Kennaway #ifndef 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 { 85ddd58736SKris Kennaway BIO *in = NULL, *out = NULL; 86ddd58736SKris Kennaway char *infile = NULL, *outfile = NULL; 87ddd58736SKris Kennaway char *keyfile = NULL; 88ddd58736SKris Kennaway char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; 89ddd58736SKris Kennaway int keyform = FORMAT_PEM; 90ddd58736SKris Kennaway char need_priv = 0, badarg = 0, rev = 0; 91ddd58736SKris Kennaway char hexdump = 0, asn1parse = 0; 92ddd58736SKris Kennaway X509 *x; 93ddd58736SKris Kennaway EVP_PKEY *pkey = NULL; 94ddd58736SKris Kennaway RSA *rsa = NULL; 95ddd58736SKris Kennaway unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; 96ddd58736SKris Kennaway int rsa_inlen, rsa_outlen = 0; 97ddd58736SKris Kennaway int keysize; 98ddd58736SKris Kennaway 99ddd58736SKris Kennaway int ret = 1; 100ddd58736SKris Kennaway 101ddd58736SKris Kennaway argc--; 102ddd58736SKris Kennaway argv++; 103ddd58736SKris Kennaway 104ddd58736SKris Kennaway if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 105ddd58736SKris Kennaway ERR_load_crypto_strings(); 106ddd58736SKris Kennaway OpenSSL_add_all_algorithms(); 107ddd58736SKris Kennaway pad = RSA_PKCS1_PADDING; 108ddd58736SKris Kennaway 109ddd58736SKris Kennaway while(argc >= 1) 110ddd58736SKris Kennaway { 111ddd58736SKris Kennaway if (!strcmp(*argv,"-in")) { 112ddd58736SKris Kennaway if (--argc < 1) badarg = 1; 113ddd58736SKris Kennaway infile= *(++argv); 114ddd58736SKris Kennaway } else if (!strcmp(*argv,"-out")) { 115ddd58736SKris Kennaway if (--argc < 1) badarg = 1; 116ddd58736SKris Kennaway outfile= *(++argv); 117ddd58736SKris Kennaway } else if(!strcmp(*argv, "-inkey")) { 118ddd58736SKris Kennaway if (--argc < 1) badarg = 1; 119ddd58736SKris Kennaway keyfile = *(++argv); 120ddd58736SKris Kennaway } else if(!strcmp(*argv, "-pubin")) { 121ddd58736SKris Kennaway key_type = KEY_PUBKEY; 122ddd58736SKris Kennaway } else if(!strcmp(*argv, "-certin")) { 123ddd58736SKris Kennaway key_type = KEY_CERT; 124ddd58736SKris Kennaway } 125ddd58736SKris Kennaway else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1; 126ddd58736SKris Kennaway else if(!strcmp(*argv, "-hexdump")) hexdump = 1; 127ddd58736SKris Kennaway else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; 128ddd58736SKris Kennaway else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; 129ddd58736SKris Kennaway else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; 130ddd58736SKris Kennaway else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; 131ddd58736SKris Kennaway else if(!strcmp(*argv, "-sign")) { 132ddd58736SKris Kennaway rsa_mode = RSA_SIGN; 133ddd58736SKris Kennaway need_priv = 1; 134ddd58736SKris Kennaway } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; 135ddd58736SKris Kennaway else if(!strcmp(*argv, "-rev")) rev = 1; 136ddd58736SKris Kennaway else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; 137ddd58736SKris Kennaway else if(!strcmp(*argv, "-decrypt")) { 138ddd58736SKris Kennaway rsa_mode = RSA_DECRYPT; 139ddd58736SKris Kennaway need_priv = 1; 140ddd58736SKris Kennaway } else badarg = 1; 141ddd58736SKris Kennaway if(badarg) { 142ddd58736SKris Kennaway usage(); 143ddd58736SKris Kennaway goto end; 144ddd58736SKris Kennaway } 145ddd58736SKris Kennaway argc--; 146ddd58736SKris Kennaway argv++; 147ddd58736SKris Kennaway } 148ddd58736SKris Kennaway 149ddd58736SKris Kennaway if(need_priv && (key_type != KEY_PRIVKEY)) { 150ddd58736SKris Kennaway BIO_printf(bio_err, "A private key is needed for this operation\n"); 151ddd58736SKris Kennaway goto end; 152ddd58736SKris Kennaway } 153ddd58736SKris Kennaway 154ddd58736SKris Kennaway /* FIXME: seed PRNG only if needed */ 155ddd58736SKris Kennaway app_RAND_load_file(NULL, bio_err, 0); 156ddd58736SKris Kennaway 157ddd58736SKris Kennaway switch(key_type) { 158ddd58736SKris Kennaway case KEY_PRIVKEY: 159ddd58736SKris Kennaway pkey = load_key(bio_err, keyfile, keyform, NULL); 160ddd58736SKris Kennaway break; 161ddd58736SKris Kennaway 162ddd58736SKris Kennaway case KEY_PUBKEY: 163ddd58736SKris Kennaway pkey = load_pubkey(bio_err, keyfile, keyform); 164ddd58736SKris Kennaway break; 165ddd58736SKris Kennaway 166ddd58736SKris Kennaway case KEY_CERT: 167ddd58736SKris Kennaway x = load_cert(bio_err, keyfile, keyform); 168ddd58736SKris Kennaway if(x) { 169ddd58736SKris Kennaway pkey = X509_get_pubkey(x); 170ddd58736SKris Kennaway X509_free(x); 171ddd58736SKris Kennaway } 172ddd58736SKris Kennaway break; 173ddd58736SKris Kennaway } 174ddd58736SKris Kennaway 175ddd58736SKris Kennaway if(!pkey) { 176ddd58736SKris Kennaway BIO_printf(bio_err, "Error loading key\n"); 177ddd58736SKris Kennaway return 1; 178ddd58736SKris Kennaway } 179ddd58736SKris Kennaway 180ddd58736SKris Kennaway rsa = EVP_PKEY_get1_RSA(pkey); 181ddd58736SKris Kennaway EVP_PKEY_free(pkey); 182ddd58736SKris Kennaway 183ddd58736SKris Kennaway if(!rsa) { 184ddd58736SKris Kennaway BIO_printf(bio_err, "Error getting RSA key\n"); 185ddd58736SKris Kennaway ERR_print_errors(bio_err); 186ddd58736SKris Kennaway goto end; 187ddd58736SKris Kennaway } 188ddd58736SKris Kennaway 189ddd58736SKris Kennaway 190ddd58736SKris Kennaway if(infile) { 191ddd58736SKris Kennaway if(!(in = BIO_new_file(infile, "rb"))) { 192ddd58736SKris Kennaway BIO_printf(bio_err, "Error Reading Input File\n"); 193ddd58736SKris Kennaway ERR_print_errors(bio_err); 194ddd58736SKris Kennaway goto end; 195ddd58736SKris Kennaway } 196ddd58736SKris Kennaway } else in = BIO_new_fp(stdin, BIO_NOCLOSE); 197ddd58736SKris Kennaway 198ddd58736SKris Kennaway if(outfile) { 199ddd58736SKris Kennaway if(!(out = BIO_new_file(outfile, "wb"))) { 200ddd58736SKris Kennaway BIO_printf(bio_err, "Error Reading Output File\n"); 201ddd58736SKris Kennaway ERR_print_errors(bio_err); 202ddd58736SKris Kennaway goto end; 203ddd58736SKris Kennaway } 204ddd58736SKris Kennaway } else { 205ddd58736SKris Kennaway out = BIO_new_fp(stdout, BIO_NOCLOSE); 206ddd58736SKris Kennaway #ifdef VMS 207ddd58736SKris Kennaway { 208ddd58736SKris Kennaway BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 209ddd58736SKris Kennaway out = BIO_push(tmpbio, out); 210ddd58736SKris Kennaway } 211ddd58736SKris Kennaway #endif 212ddd58736SKris Kennaway } 213ddd58736SKris Kennaway 214ddd58736SKris Kennaway keysize = RSA_size(rsa); 215ddd58736SKris Kennaway 216ddd58736SKris Kennaway rsa_in = OPENSSL_malloc(keysize * 2); 217ddd58736SKris Kennaway rsa_out = OPENSSL_malloc(keysize); 218ddd58736SKris Kennaway 219ddd58736SKris Kennaway /* Read the input data */ 220ddd58736SKris Kennaway rsa_inlen = BIO_read(in, rsa_in, keysize * 2); 221ddd58736SKris Kennaway if(rsa_inlen <= 0) { 222ddd58736SKris Kennaway BIO_printf(bio_err, "Error reading input Data\n"); 223ddd58736SKris Kennaway exit(1); 224ddd58736SKris Kennaway } 225ddd58736SKris Kennaway if(rev) { 226ddd58736SKris Kennaway int i; 227ddd58736SKris Kennaway unsigned char ctmp; 228ddd58736SKris Kennaway for(i = 0; i < rsa_inlen/2; i++) { 229ddd58736SKris Kennaway ctmp = rsa_in[i]; 230ddd58736SKris Kennaway rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; 231ddd58736SKris Kennaway rsa_in[rsa_inlen - 1 - i] = ctmp; 232ddd58736SKris Kennaway } 233ddd58736SKris Kennaway } 234ddd58736SKris Kennaway switch(rsa_mode) { 235ddd58736SKris Kennaway 236ddd58736SKris Kennaway case RSA_VERIFY: 237ddd58736SKris Kennaway rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 238ddd58736SKris Kennaway break; 239ddd58736SKris Kennaway 240ddd58736SKris Kennaway case RSA_SIGN: 241ddd58736SKris Kennaway rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 242ddd58736SKris Kennaway break; 243ddd58736SKris Kennaway 244ddd58736SKris Kennaway case RSA_ENCRYPT: 245ddd58736SKris Kennaway rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 246ddd58736SKris Kennaway break; 247ddd58736SKris Kennaway 248ddd58736SKris Kennaway case RSA_DECRYPT: 249ddd58736SKris Kennaway rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 250ddd58736SKris Kennaway break; 251ddd58736SKris Kennaway 252ddd58736SKris Kennaway } 253ddd58736SKris Kennaway 254ddd58736SKris Kennaway if(rsa_outlen <= 0) { 255ddd58736SKris Kennaway BIO_printf(bio_err, "RSA operation error\n"); 256ddd58736SKris Kennaway ERR_print_errors(bio_err); 257ddd58736SKris Kennaway goto end; 258ddd58736SKris Kennaway } 259ddd58736SKris Kennaway ret = 0; 260ddd58736SKris Kennaway if(asn1parse) { 261ddd58736SKris Kennaway if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { 262ddd58736SKris Kennaway ERR_print_errors(bio_err); 263ddd58736SKris Kennaway } 264ddd58736SKris Kennaway } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); 265ddd58736SKris Kennaway else BIO_write(out, rsa_out, rsa_outlen); 266ddd58736SKris Kennaway end: 267ddd58736SKris Kennaway RSA_free(rsa); 268ddd58736SKris Kennaway BIO_free(in); 269ddd58736SKris Kennaway BIO_free_all(out); 270ddd58736SKris Kennaway if(rsa_in) OPENSSL_free(rsa_in); 271ddd58736SKris Kennaway if(rsa_out) OPENSSL_free(rsa_out); 272ddd58736SKris Kennaway return ret; 273ddd58736SKris Kennaway } 274ddd58736SKris Kennaway 275ddd58736SKris Kennaway static void usage() 276ddd58736SKris Kennaway { 277ddd58736SKris Kennaway BIO_printf(bio_err, "Usage: rsautl [options]\n"); 278ddd58736SKris Kennaway BIO_printf(bio_err, "-in file input file\n"); 279ddd58736SKris Kennaway BIO_printf(bio_err, "-out file output file\n"); 280ddd58736SKris Kennaway BIO_printf(bio_err, "-inkey file input key\n"); 281ddd58736SKris Kennaway BIO_printf(bio_err, "-pubin input is an RSA public\n"); 282ddd58736SKris Kennaway BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n"); 283ddd58736SKris Kennaway BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); 284ddd58736SKris Kennaway BIO_printf(bio_err, "-raw use no padding\n"); 285ddd58736SKris Kennaway BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n"); 286ddd58736SKris Kennaway BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); 287ddd58736SKris Kennaway BIO_printf(bio_err, "-sign sign with private key\n"); 288ddd58736SKris Kennaway BIO_printf(bio_err, "-verify verify with public key\n"); 289ddd58736SKris Kennaway BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 290ddd58736SKris Kennaway BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 291ddd58736SKris Kennaway BIO_printf(bio_err, "-hexdump hex dump output\n"); 292ddd58736SKris Kennaway } 293ddd58736SKris Kennaway 294de7cdddaSKris Kennaway #endif 295