rsautl.c revision 68651
168651Skris/* rsautl.c */ 268651Skris/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 368651Skris * project 2000. 468651Skris */ 568651Skris/* ==================================================================== 668651Skris * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 768651Skris * 868651Skris * Redistribution and use in source and binary forms, with or without 968651Skris * modification, are permitted provided that the following conditions 1068651Skris * are met: 1168651Skris * 1268651Skris * 1. Redistributions of source code must retain the above copyright 1368651Skris * notice, this list of conditions and the following disclaimer. 1468651Skris * 1568651Skris * 2. Redistributions in binary form must reproduce the above copyright 1668651Skris * notice, this list of conditions and the following disclaimer in 1768651Skris * the documentation and/or other materials provided with the 1868651Skris * distribution. 1968651Skris * 2068651Skris * 3. All advertising materials mentioning features or use of this 2168651Skris * software must display the following acknowledgment: 2268651Skris * "This product includes software developed by the OpenSSL Project 2368651Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2468651Skris * 2568651Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2668651Skris * endorse or promote products derived from this software without 2768651Skris * prior written permission. For written permission, please contact 2868651Skris * licensing@OpenSSL.org. 2968651Skris * 3068651Skris * 5. Products derived from this software may not be called "OpenSSL" 3168651Skris * nor may "OpenSSL" appear in their names without prior written 3268651Skris * permission of the OpenSSL Project. 3368651Skris * 3468651Skris * 6. Redistributions of any form whatsoever must retain the following 3568651Skris * acknowledgment: 3668651Skris * "This product includes software developed by the OpenSSL Project 3768651Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3868651Skris * 3968651Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4068651Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4168651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4268651Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4368651Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4468651Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4568651Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4668651Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4768651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4868651Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4968651Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5068651Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5168651Skris * ==================================================================== 5268651Skris * 5368651Skris * This product includes cryptographic software written by Eric Young 5468651Skris * (eay@cryptsoft.com). This product includes software written by Tim 5568651Skris * Hudson (tjh@cryptsoft.com). 5668651Skris * 5768651Skris */ 5868651Skris#include "apps.h" 5968651Skris#include <string.h> 6068651Skris#include <openssl/err.h> 6168651Skris#include <openssl/pem.h> 6268651Skris 6368651Skris#define RSA_SIGN 1 6468651Skris#define RSA_VERIFY 2 6568651Skris#define RSA_ENCRYPT 3 6668651Skris#define RSA_DECRYPT 4 6768651Skris 6868651Skris#define KEY_PRIVKEY 1 6968651Skris#define KEY_PUBKEY 2 7068651Skris#define KEY_CERT 3 7168651Skris 7268651Skrisstatic void usage(void); 7368651Skris 7468651Skris#undef PROG 7568651Skris 7668651Skris#define PROG rsautl_main 7768651Skris 7868651Skrisint MAIN(int argc, char **); 7968651Skris 8068651Skrisint MAIN(int argc, char **argv) 8168651Skris{ 8268651Skris BIO *in = NULL, *out = NULL; 8368651Skris char *infile = NULL, *outfile = NULL; 8468651Skris char *keyfile = NULL; 8568651Skris char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; 8668651Skris int keyform = FORMAT_PEM; 8768651Skris char need_priv = 0, badarg = 0, rev = 0; 8868651Skris char hexdump = 0, asn1parse = 0; 8968651Skris X509 *x; 9068651Skris EVP_PKEY *pkey = NULL; 9168651Skris RSA *rsa = NULL; 9268651Skris unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; 9368651Skris int rsa_inlen, rsa_outlen = 0; 9468651Skris int keysize; 9568651Skris 9668651Skris int ret = 1; 9768651Skris 9868651Skris argc--; 9968651Skris argv++; 10068651Skris 10168651Skris if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 10268651Skris ERR_load_crypto_strings(); 10368651Skris OpenSSL_add_all_algorithms(); 10468651Skris pad = RSA_PKCS1_PADDING; 10568651Skris 10668651Skris while(argc >= 1) 10768651Skris { 10868651Skris if (!strcmp(*argv,"-in")) { 10968651Skris if (--argc < 1) badarg = 1; 11068651Skris infile= *(++argv); 11168651Skris } else if (!strcmp(*argv,"-out")) { 11268651Skris if (--argc < 1) badarg = 1; 11368651Skris outfile= *(++argv); 11468651Skris } else if(!strcmp(*argv, "-inkey")) { 11568651Skris if (--argc < 1) badarg = 1; 11668651Skris keyfile = *(++argv); 11768651Skris } else if(!strcmp(*argv, "-pubin")) { 11868651Skris key_type = KEY_PUBKEY; 11968651Skris } else if(!strcmp(*argv, "-certin")) { 12068651Skris key_type = KEY_CERT; 12168651Skris } 12268651Skris else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1; 12368651Skris else if(!strcmp(*argv, "-hexdump")) hexdump = 1; 12468651Skris else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; 12568651Skris else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; 12668651Skris else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; 12768651Skris else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; 12868651Skris else if(!strcmp(*argv, "-sign")) { 12968651Skris rsa_mode = RSA_SIGN; 13068651Skris need_priv = 1; 13168651Skris } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; 13268651Skris else if(!strcmp(*argv, "-rev")) rev = 1; 13368651Skris else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; 13468651Skris else if(!strcmp(*argv, "-decrypt")) { 13568651Skris rsa_mode = RSA_DECRYPT; 13668651Skris need_priv = 1; 13768651Skris } else badarg = 1; 13868651Skris if(badarg) { 13968651Skris usage(); 14068651Skris goto end; 14168651Skris } 14268651Skris argc--; 14368651Skris argv++; 14468651Skris } 14568651Skris 14668651Skris if(need_priv && (key_type != KEY_PRIVKEY)) { 14768651Skris BIO_printf(bio_err, "A private key is needed for this operation\n"); 14868651Skris goto end; 14968651Skris } 15068651Skris 15168651Skris/* FIXME: seed PRNG only if needed */ 15268651Skris app_RAND_load_file(NULL, bio_err, 0); 15368651Skris 15468651Skris switch(key_type) { 15568651Skris case KEY_PRIVKEY: 15668651Skris pkey = load_key(bio_err, keyfile, keyform, NULL); 15768651Skris break; 15868651Skris 15968651Skris case KEY_PUBKEY: 16068651Skris pkey = load_pubkey(bio_err, keyfile, keyform); 16168651Skris break; 16268651Skris 16368651Skris case KEY_CERT: 16468651Skris x = load_cert(bio_err, keyfile, keyform); 16568651Skris if(x) { 16668651Skris pkey = X509_get_pubkey(x); 16768651Skris X509_free(x); 16868651Skris } 16968651Skris break; 17068651Skris } 17168651Skris 17268651Skris if(!pkey) { 17368651Skris BIO_printf(bio_err, "Error loading key\n"); 17468651Skris return 1; 17568651Skris } 17668651Skris 17768651Skris rsa = EVP_PKEY_get1_RSA(pkey); 17868651Skris EVP_PKEY_free(pkey); 17968651Skris 18068651Skris if(!rsa) { 18168651Skris BIO_printf(bio_err, "Error getting RSA key\n"); 18268651Skris ERR_print_errors(bio_err); 18368651Skris goto end; 18468651Skris } 18568651Skris 18668651Skris 18768651Skris if(infile) { 18868651Skris if(!(in = BIO_new_file(infile, "rb"))) { 18968651Skris BIO_printf(bio_err, "Error Reading Input File\n"); 19068651Skris ERR_print_errors(bio_err); 19168651Skris goto end; 19268651Skris } 19368651Skris } else in = BIO_new_fp(stdin, BIO_NOCLOSE); 19468651Skris 19568651Skris if(outfile) { 19668651Skris if(!(out = BIO_new_file(outfile, "wb"))) { 19768651Skris BIO_printf(bio_err, "Error Reading Output File\n"); 19868651Skris ERR_print_errors(bio_err); 19968651Skris goto end; 20068651Skris } 20168651Skris } else { 20268651Skris out = BIO_new_fp(stdout, BIO_NOCLOSE); 20368651Skris#ifdef VMS 20468651Skris { 20568651Skris BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 20668651Skris out = BIO_push(tmpbio, out); 20768651Skris } 20868651Skris#endif 20968651Skris } 21068651Skris 21168651Skris keysize = RSA_size(rsa); 21268651Skris 21368651Skris rsa_in = OPENSSL_malloc(keysize * 2); 21468651Skris rsa_out = OPENSSL_malloc(keysize); 21568651Skris 21668651Skris /* Read the input data */ 21768651Skris rsa_inlen = BIO_read(in, rsa_in, keysize * 2); 21868651Skris if(rsa_inlen <= 0) { 21968651Skris BIO_printf(bio_err, "Error reading input Data\n"); 22068651Skris exit(1); 22168651Skris } 22268651Skris if(rev) { 22368651Skris int i; 22468651Skris unsigned char ctmp; 22568651Skris for(i = 0; i < rsa_inlen/2; i++) { 22668651Skris ctmp = rsa_in[i]; 22768651Skris rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; 22868651Skris rsa_in[rsa_inlen - 1 - i] = ctmp; 22968651Skris } 23068651Skris } 23168651Skris switch(rsa_mode) { 23268651Skris 23368651Skris case RSA_VERIFY: 23468651Skris rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 23568651Skris break; 23668651Skris 23768651Skris case RSA_SIGN: 23868651Skris rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 23968651Skris break; 24068651Skris 24168651Skris case RSA_ENCRYPT: 24268651Skris rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 24368651Skris break; 24468651Skris 24568651Skris case RSA_DECRYPT: 24668651Skris rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 24768651Skris break; 24868651Skris 24968651Skris } 25068651Skris 25168651Skris if(rsa_outlen <= 0) { 25268651Skris BIO_printf(bio_err, "RSA operation error\n"); 25368651Skris ERR_print_errors(bio_err); 25468651Skris goto end; 25568651Skris } 25668651Skris ret = 0; 25768651Skris if(asn1parse) { 25868651Skris if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { 25968651Skris ERR_print_errors(bio_err); 26068651Skris } 26168651Skris } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); 26268651Skris else BIO_write(out, rsa_out, rsa_outlen); 26368651Skris end: 26468651Skris RSA_free(rsa); 26568651Skris BIO_free(in); 26668651Skris BIO_free_all(out); 26768651Skris if(rsa_in) OPENSSL_free(rsa_in); 26868651Skris if(rsa_out) OPENSSL_free(rsa_out); 26968651Skris return ret; 27068651Skris} 27168651Skris 27268651Skrisstatic void usage() 27368651Skris{ 27468651Skris BIO_printf(bio_err, "Usage: rsautl [options]\n"); 27568651Skris BIO_printf(bio_err, "-in file input file\n"); 27668651Skris BIO_printf(bio_err, "-out file output file\n"); 27768651Skris BIO_printf(bio_err, "-inkey file input key\n"); 27868651Skris BIO_printf(bio_err, "-pubin input is an RSA public\n"); 27968651Skris BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n"); 28068651Skris BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); 28168651Skris BIO_printf(bio_err, "-raw use no padding\n"); 28268651Skris BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n"); 28368651Skris BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); 28468651Skris BIO_printf(bio_err, "-sign sign with private key\n"); 28568651Skris BIO_printf(bio_err, "-verify verify with public key\n"); 28668651Skris BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 28768651Skris BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 28868651Skris BIO_printf(bio_err, "-hexdump hex dump output\n"); 28968651Skris} 29068651Skris 291