168651Skris/* rsautl.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296465Sdelphij * 2000. 568651Skris */ 668651Skris/* ==================================================================== 768651Skris * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 868651Skris * 968651Skris * Redistribution and use in source and binary forms, with or without 1068651Skris * modification, are permitted provided that the following conditions 1168651Skris * are met: 1268651Skris * 1368651Skris * 1. Redistributions of source code must retain the above copyright 14296465Sdelphij * notice, this list of conditions and the following disclaimer. 1568651Skris * 1668651Skris * 2. Redistributions in binary form must reproduce the above copyright 1768651Skris * notice, this list of conditions and the following disclaimer in 1868651Skris * the documentation and/or other materials provided with the 1968651Skris * distribution. 2068651Skris * 2168651Skris * 3. All advertising materials mentioning features or use of this 2268651Skris * software must display the following acknowledgment: 2368651Skris * "This product includes software developed by the OpenSSL Project 2468651Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2568651Skris * 2668651Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2768651Skris * endorse or promote products derived from this software without 2868651Skris * prior written permission. For written permission, please contact 2968651Skris * licensing@OpenSSL.org. 3068651Skris * 3168651Skris * 5. Products derived from this software may not be called "OpenSSL" 3268651Skris * nor may "OpenSSL" appear in their names without prior written 3368651Skris * permission of the OpenSSL Project. 3468651Skris * 3568651Skris * 6. Redistributions of any form whatsoever must retain the following 3668651Skris * acknowledgment: 3768651Skris * "This product includes software developed by the OpenSSL Project 3868651Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3968651Skris * 4068651Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4168651Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4268651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4368651Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4468651Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4568651Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4668651Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4768651Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4968651Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5068651Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5168651Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5268651Skris * ==================================================================== 5368651Skris * 5468651Skris * This product includes cryptographic software written by Eric Young 5568651Skris * (eay@cryptsoft.com). This product includes software written by Tim 5668651Skris * Hudson (tjh@cryptsoft.com). 5768651Skris * 5868651Skris */ 5972613Skris 60160814Ssimon#include <openssl/opensslconf.h> 61109998Smarkm#ifndef OPENSSL_NO_RSA 6272613Skris 63296465Sdelphij# include "apps.h" 64296465Sdelphij# include <string.h> 65296465Sdelphij# include <openssl/err.h> 66296465Sdelphij# include <openssl/pem.h> 67296465Sdelphij# include <openssl/rsa.h> 6868651Skris 69296465Sdelphij# define RSA_SIGN 1 70296465Sdelphij# define RSA_VERIFY 2 71296465Sdelphij# define RSA_ENCRYPT 3 72296465Sdelphij# define RSA_DECRYPT 4 7368651Skris 74296465Sdelphij# define KEY_PRIVKEY 1 75296465Sdelphij# define KEY_PUBKEY 2 76296465Sdelphij# define KEY_CERT 3 7768651Skris 7868651Skrisstatic void usage(void); 7968651Skris 80296465Sdelphij# undef PROG 8168651Skris 82296465Sdelphij# define PROG rsautl_main 8368651Skris 8468651Skrisint MAIN(int argc, char **); 8568651Skris 8668651Skrisint MAIN(int argc, char **argv) 8768651Skris{ 88296465Sdelphij ENGINE *e = NULL; 89296465Sdelphij BIO *in = NULL, *out = NULL; 90296465Sdelphij char *infile = NULL, *outfile = NULL; 91296465Sdelphij# ifndef OPENSSL_NO_ENGINE 92296465Sdelphij char *engine = NULL; 93296465Sdelphij# endif 94296465Sdelphij char *keyfile = NULL; 95296465Sdelphij char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; 96296465Sdelphij int keyform = FORMAT_PEM; 97296465Sdelphij char need_priv = 0, badarg = 0, rev = 0; 98296465Sdelphij char hexdump = 0, asn1parse = 0; 99296465Sdelphij X509 *x; 100296465Sdelphij EVP_PKEY *pkey = NULL; 101296465Sdelphij RSA *rsa = NULL; 102296465Sdelphij unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; 103296465Sdelphij char *passargin = NULL, *passin = NULL; 104296465Sdelphij int rsa_inlen, rsa_outlen = 0; 105296465Sdelphij int keysize; 10668651Skris 107296465Sdelphij int ret = 1; 10868651Skris 109296465Sdelphij argc--; 110296465Sdelphij argv++; 11168651Skris 112296465Sdelphij if (!bio_err) 113296465Sdelphij bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 114109998Smarkm 115296465Sdelphij if (!load_config(bio_err, NULL)) 116296465Sdelphij goto end; 117296465Sdelphij ERR_load_crypto_strings(); 118296465Sdelphij OpenSSL_add_all_algorithms(); 119296465Sdelphij pad = RSA_PKCS1_PADDING; 12068651Skris 121296465Sdelphij while (argc >= 1) { 122296465Sdelphij if (!strcmp(*argv, "-in")) { 123296465Sdelphij if (--argc < 1) 124296465Sdelphij badarg = 1; 125296465Sdelphij else 126296465Sdelphij infile = *(++argv); 127296465Sdelphij } else if (!strcmp(*argv, "-out")) { 128296465Sdelphij if (--argc < 1) 129296465Sdelphij badarg = 1; 130296465Sdelphij else 131296465Sdelphij outfile = *(++argv); 132296465Sdelphij } else if (!strcmp(*argv, "-inkey")) { 133296465Sdelphij if (--argc < 1) 134296465Sdelphij badarg = 1; 135296465Sdelphij else 136296465Sdelphij keyfile = *(++argv); 137296465Sdelphij } else if (!strcmp(*argv, "-passin")) { 138296465Sdelphij if (--argc < 1) 139296465Sdelphij badarg = 1; 140296465Sdelphij else 141296465Sdelphij passargin = *(++argv); 142296465Sdelphij } else if (strcmp(*argv, "-keyform") == 0) { 143296465Sdelphij if (--argc < 1) 144296465Sdelphij badarg = 1; 145296465Sdelphij else 146296465Sdelphij keyform = str2fmt(*(++argv)); 147296465Sdelphij# ifndef OPENSSL_NO_ENGINE 148296465Sdelphij } else if (!strcmp(*argv, "-engine")) { 149296465Sdelphij if (--argc < 1) 150296465Sdelphij badarg = 1; 151296465Sdelphij else 152296465Sdelphij engine = *(++argv); 153296465Sdelphij# endif 154296465Sdelphij } else if (!strcmp(*argv, "-pubin")) { 155296465Sdelphij key_type = KEY_PUBKEY; 156296465Sdelphij } else if (!strcmp(*argv, "-certin")) { 157296465Sdelphij key_type = KEY_CERT; 158296465Sdelphij } else if (!strcmp(*argv, "-asn1parse")) 159296465Sdelphij asn1parse = 1; 160296465Sdelphij else if (!strcmp(*argv, "-hexdump")) 161296465Sdelphij hexdump = 1; 162296465Sdelphij else if (!strcmp(*argv, "-raw")) 163296465Sdelphij pad = RSA_NO_PADDING; 164296465Sdelphij else if (!strcmp(*argv, "-oaep")) 165296465Sdelphij pad = RSA_PKCS1_OAEP_PADDING; 166296465Sdelphij else if (!strcmp(*argv, "-ssl")) 167296465Sdelphij pad = RSA_SSLV23_PADDING; 168296465Sdelphij else if (!strcmp(*argv, "-pkcs")) 169296465Sdelphij pad = RSA_PKCS1_PADDING; 170296465Sdelphij else if (!strcmp(*argv, "-x931")) 171296465Sdelphij pad = RSA_X931_PADDING; 172296465Sdelphij else if (!strcmp(*argv, "-sign")) { 173296465Sdelphij rsa_mode = RSA_SIGN; 174296465Sdelphij need_priv = 1; 175296465Sdelphij } else if (!strcmp(*argv, "-verify")) 176296465Sdelphij rsa_mode = RSA_VERIFY; 177296465Sdelphij else if (!strcmp(*argv, "-rev")) 178296465Sdelphij rev = 1; 179296465Sdelphij else if (!strcmp(*argv, "-encrypt")) 180296465Sdelphij rsa_mode = RSA_ENCRYPT; 181296465Sdelphij else if (!strcmp(*argv, "-decrypt")) { 182296465Sdelphij rsa_mode = RSA_DECRYPT; 183296465Sdelphij need_priv = 1; 184296465Sdelphij } else 185296465Sdelphij badarg = 1; 186296465Sdelphij if (badarg) { 187296465Sdelphij usage(); 188296465Sdelphij goto end; 189296465Sdelphij } 190296465Sdelphij argc--; 191296465Sdelphij argv++; 192296465Sdelphij } 19368651Skris 194296465Sdelphij if (need_priv && (key_type != KEY_PRIVKEY)) { 195296465Sdelphij BIO_printf(bio_err, "A private key is needed for this operation\n"); 196296465Sdelphij goto end; 197296465Sdelphij } 198296465Sdelphij# ifndef OPENSSL_NO_ENGINE 199296465Sdelphij e = setup_engine(bio_err, engine, 0); 200296465Sdelphij# endif 201296465Sdelphij if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 202296465Sdelphij BIO_printf(bio_err, "Error getting password\n"); 203296465Sdelphij goto end; 204296465Sdelphij } 205109998Smarkm 20668651Skris/* FIXME: seed PRNG only if needed */ 207296465Sdelphij app_RAND_load_file(NULL, bio_err, 0); 20868651Skris 209296465Sdelphij switch (key_type) { 210296465Sdelphij case KEY_PRIVKEY: 211296465Sdelphij pkey = load_key(bio_err, keyfile, keyform, 0, 212296465Sdelphij passin, e, "Private Key"); 213296465Sdelphij break; 21468651Skris 215296465Sdelphij case KEY_PUBKEY: 216296465Sdelphij pkey = load_pubkey(bio_err, keyfile, keyform, 0, 217296465Sdelphij NULL, e, "Public Key"); 218296465Sdelphij break; 21968651Skris 220296465Sdelphij case KEY_CERT: 221296465Sdelphij x = load_cert(bio_err, keyfile, keyform, NULL, e, "Certificate"); 222296465Sdelphij if (x) { 223296465Sdelphij pkey = X509_get_pubkey(x); 224296465Sdelphij X509_free(x); 225296465Sdelphij } 226296465Sdelphij break; 227296465Sdelphij } 22868651Skris 229296465Sdelphij if (!pkey) { 230296465Sdelphij return 1; 231296465Sdelphij } 23268651Skris 233296465Sdelphij rsa = EVP_PKEY_get1_RSA(pkey); 234296465Sdelphij EVP_PKEY_free(pkey); 23568651Skris 236296465Sdelphij if (!rsa) { 237296465Sdelphij BIO_printf(bio_err, "Error getting RSA key\n"); 238296465Sdelphij ERR_print_errors(bio_err); 239296465Sdelphij goto end; 240296465Sdelphij } 24168651Skris 242296465Sdelphij if (infile) { 243296465Sdelphij if (!(in = BIO_new_file(infile, "rb"))) { 244296465Sdelphij BIO_printf(bio_err, "Error Reading Input File\n"); 245296465Sdelphij ERR_print_errors(bio_err); 246296465Sdelphij goto end; 247296465Sdelphij } 248296465Sdelphij } else 249296465Sdelphij in = BIO_new_fp(stdin, BIO_NOCLOSE); 25068651Skris 251296465Sdelphij if (outfile) { 252296465Sdelphij if (!(out = BIO_new_file(outfile, "wb"))) { 253296465Sdelphij BIO_printf(bio_err, "Error Reading Output File\n"); 254296465Sdelphij ERR_print_errors(bio_err); 255296465Sdelphij goto end; 256296465Sdelphij } 257296465Sdelphij } else { 258296465Sdelphij out = BIO_new_fp(stdout, BIO_NOCLOSE); 259296465Sdelphij# ifdef OPENSSL_SYS_VMS 260296465Sdelphij { 261296465Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 262296465Sdelphij out = BIO_push(tmpbio, out); 263296465Sdelphij } 264296465Sdelphij# endif 265296465Sdelphij } 26668651Skris 267296465Sdelphij keysize = RSA_size(rsa); 26868651Skris 269296465Sdelphij rsa_in = OPENSSL_malloc(keysize * 2); 270296465Sdelphij rsa_out = OPENSSL_malloc(keysize); 27168651Skris 272296465Sdelphij /* Read the input data */ 273296465Sdelphij rsa_inlen = BIO_read(in, rsa_in, keysize * 2); 274296465Sdelphij if (rsa_inlen <= 0) { 275296465Sdelphij BIO_printf(bio_err, "Error reading input Data\n"); 276296465Sdelphij exit(1); 277296465Sdelphij } 278296465Sdelphij if (rev) { 279296465Sdelphij int i; 280296465Sdelphij unsigned char ctmp; 281296465Sdelphij for (i = 0; i < rsa_inlen / 2; i++) { 282296465Sdelphij ctmp = rsa_in[i]; 283296465Sdelphij rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; 284296465Sdelphij rsa_in[rsa_inlen - 1 - i] = ctmp; 285296465Sdelphij } 286296465Sdelphij } 287296465Sdelphij switch (rsa_mode) { 28868651Skris 289296465Sdelphij case RSA_VERIFY: 290296465Sdelphij rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 291296465Sdelphij break; 29268651Skris 293296465Sdelphij case RSA_SIGN: 294296465Sdelphij rsa_outlen = 295296465Sdelphij RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 296296465Sdelphij break; 29768651Skris 298296465Sdelphij case RSA_ENCRYPT: 299296465Sdelphij rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 300296465Sdelphij break; 30168651Skris 302296465Sdelphij case RSA_DECRYPT: 303296465Sdelphij rsa_outlen = 304296465Sdelphij RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 305296465Sdelphij break; 30668651Skris 307296465Sdelphij } 30868651Skris 309296465Sdelphij if (rsa_outlen <= 0) { 310296465Sdelphij BIO_printf(bio_err, "RSA operation error\n"); 311296465Sdelphij ERR_print_errors(bio_err); 312296465Sdelphij goto end; 313296465Sdelphij } 314296465Sdelphij ret = 0; 315296465Sdelphij if (asn1parse) { 316296465Sdelphij if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { 317296465Sdelphij ERR_print_errors(bio_err); 318296465Sdelphij } 319296465Sdelphij } else if (hexdump) 320296465Sdelphij BIO_dump(out, (char *)rsa_out, rsa_outlen); 321296465Sdelphij else 322296465Sdelphij BIO_write(out, rsa_out, rsa_outlen); 323296465Sdelphij end: 324296465Sdelphij RSA_free(rsa); 325296465Sdelphij BIO_free(in); 326296465Sdelphij BIO_free_all(out); 327296465Sdelphij if (rsa_in) 328296465Sdelphij OPENSSL_free(rsa_in); 329296465Sdelphij if (rsa_out) 330296465Sdelphij OPENSSL_free(rsa_out); 331296465Sdelphij if (passin) 332296465Sdelphij OPENSSL_free(passin); 333296465Sdelphij return ret; 33468651Skris} 33568651Skris 33668651Skrisstatic void usage() 33768651Skris{ 338296465Sdelphij BIO_printf(bio_err, "Usage: rsautl [options]\n"); 339296465Sdelphij BIO_printf(bio_err, "-in file input file\n"); 340296465Sdelphij BIO_printf(bio_err, "-out file output file\n"); 341296465Sdelphij BIO_printf(bio_err, "-inkey file input key\n"); 342296465Sdelphij BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); 343296465Sdelphij BIO_printf(bio_err, "-pubin input is an RSA public\n"); 344296465Sdelphij BIO_printf(bio_err, 345296465Sdelphij "-certin input is a certificate carrying an RSA public key\n"); 346296465Sdelphij BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); 347296465Sdelphij BIO_printf(bio_err, "-raw use no padding\n"); 348296465Sdelphij BIO_printf(bio_err, 349296465Sdelphij "-pkcs use PKCS#1 v1.5 padding (default)\n"); 350296465Sdelphij BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); 351296465Sdelphij BIO_printf(bio_err, "-sign sign with private key\n"); 352296465Sdelphij BIO_printf(bio_err, "-verify verify with public key\n"); 353296465Sdelphij BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 354296465Sdelphij BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 355296465Sdelphij BIO_printf(bio_err, "-hexdump hex dump output\n"); 356296465Sdelphij# ifndef OPENSSL_NO_ENGINE 357296465Sdelphij BIO_printf(bio_err, 358296465Sdelphij "-engine e use engine e, possibly a hardware device.\n"); 359296465Sdelphij BIO_printf(bio_err, "-passin arg pass phrase source\n"); 360296465Sdelphij# endif 361109998Smarkm 36268651Skris} 36368651Skris 36472613Skris#endif 365