rsautl.c revision 296465
11541Srgrimes/* rsautl.c */ 21541Srgrimes/* 31541Srgrimes * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 41541Srgrimes * 2000. 51541Srgrimes */ 61541Srgrimes/* ==================================================================== 71541Srgrimes * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 81541Srgrimes * 91541Srgrimes * Redistribution and use in source and binary forms, with or without 101541Srgrimes * modification, are permitted provided that the following conditions 111541Srgrimes * are met: 121541Srgrimes * 131541Srgrimes * 1. Redistributions of source code must retain the above copyright 141541Srgrimes * notice, this list of conditions and the following disclaimer. 151541Srgrimes * 161541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 171541Srgrimes * notice, this list of conditions and the following disclaimer in 181541Srgrimes * the documentation and/or other materials provided with the 191541Srgrimes * distribution. 201541Srgrimes * 211541Srgrimes * 3. All advertising materials mentioning features or use of this 221541Srgrimes * software must display the following acknowledgment: 231541Srgrimes * "This product includes software developed by the OpenSSL Project 241541Srgrimes * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 251541Srgrimes * 261541Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 271541Srgrimes * endorse or promote products derived from this software without 281541Srgrimes * prior written permission. For written permission, please contact 291541Srgrimes * licensing@OpenSSL.org. 301541Srgrimes * 311541Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 321541Srgrimes * nor may "OpenSSL" appear in their names without prior written 331541Srgrimes * permission of the OpenSSL Project. 341541Srgrimes * 351541Srgrimes * 6. Redistributions of any form whatsoever must retain the following 361541Srgrimes * acknowledgment: 371541Srgrimes * "This product includes software developed by the OpenSSL Project 381541Srgrimes * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 391541Srgrimes * 401541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 411541Srgrimes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 421541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 431541Srgrimes * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 441541Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 451541Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 461541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 471541Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 481541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 491541Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 501541Srgrimes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 511541Srgrimes * OF THE POSSIBILITY OF SUCH DAMAGE. 521541Srgrimes * ==================================================================== 531541Srgrimes * 541541Srgrimes * This product includes cryptographic software written by Eric Young 551541Srgrimes * (eay@cryptsoft.com). This product includes software written by Tim 561541Srgrimes * Hudson (tjh@cryptsoft.com). 571541Srgrimes * 581541Srgrimes */ 591541Srgrimes 601541Srgrimes#include <openssl/opensslconf.h> 611541Srgrimes#ifndef OPENSSL_NO_RSA 621541Srgrimes 631541Srgrimes# include "apps.h" 641541Srgrimes# include <string.h> 651541Srgrimes# include <openssl/err.h> 661541Srgrimes# include <openssl/pem.h> 671541Srgrimes# include <openssl/rsa.h> 681541Srgrimes 691541Srgrimes# define RSA_SIGN 1 701541Srgrimes# define RSA_VERIFY 2 711541Srgrimes# define RSA_ENCRYPT 3 721541Srgrimes# define RSA_DECRYPT 4 731541Srgrimes 741541Srgrimes# define KEY_PRIVKEY 1 751541Srgrimes# define KEY_PUBKEY 2 761541Srgrimes# define KEY_CERT 3 771541Srgrimes 781541Srgrimesstatic void usage(void); 791541Srgrimes 801541Srgrimes# undef PROG 811541Srgrimes 821541Srgrimes# define PROG rsautl_main 831541Srgrimes 841541Srgrimesint MAIN(int argc, char **); 851541Srgrimes 861541Srgrimesint MAIN(int argc, char **argv) 871541Srgrimes{ 881541Srgrimes ENGINE *e = NULL; 891541Srgrimes BIO *in = NULL, *out = NULL; 901541Srgrimes char *infile = NULL, *outfile = NULL; 911541Srgrimes# ifndef OPENSSL_NO_ENGINE 921541Srgrimes char *engine = NULL; 931541Srgrimes# endif 941541Srgrimes char *keyfile = NULL; 951541Srgrimes char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; 961541Srgrimes int keyform = FORMAT_PEM; 971541Srgrimes char need_priv = 0, badarg = 0, rev = 0; 981541Srgrimes char hexdump = 0, asn1parse = 0; 991541Srgrimes X509 *x; 1001541Srgrimes EVP_PKEY *pkey = NULL; 1011541Srgrimes RSA *rsa = NULL; 1021541Srgrimes unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; 1031541Srgrimes char *passargin = NULL, *passin = NULL; 1041541Srgrimes int rsa_inlen, rsa_outlen = 0; 1051541Srgrimes int keysize; 1061541Srgrimes 1071541Srgrimes int ret = 1; 1081541Srgrimes 1091541Srgrimes argc--; 1101541Srgrimes argv++; 1111541Srgrimes 1121541Srgrimes if (!bio_err) 1131541Srgrimes bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 1141541Srgrimes 1151541Srgrimes if (!load_config(bio_err, NULL)) 1161541Srgrimes goto end; 1171541Srgrimes ERR_load_crypto_strings(); 1181541Srgrimes OpenSSL_add_all_algorithms(); 1191541Srgrimes pad = RSA_PKCS1_PADDING; 1201541Srgrimes 1211541Srgrimes while (argc >= 1) { 1221541Srgrimes if (!strcmp(*argv, "-in")) { 1231541Srgrimes if (--argc < 1) 1241541Srgrimes badarg = 1; 1251541Srgrimes else 1261541Srgrimes infile = *(++argv); 1271541Srgrimes } else if (!strcmp(*argv, "-out")) { 1281541Srgrimes if (--argc < 1) 1291541Srgrimes badarg = 1; 1301541Srgrimes else 1311541Srgrimes outfile = *(++argv); 1321541Srgrimes } else if (!strcmp(*argv, "-inkey")) { 1331541Srgrimes if (--argc < 1) 1341541Srgrimes badarg = 1; 1351541Srgrimes else 1361541Srgrimes keyfile = *(++argv); 1371541Srgrimes } else if (!strcmp(*argv, "-passin")) { 1381541Srgrimes if (--argc < 1) 1391541Srgrimes badarg = 1; 1401541Srgrimes else 1411541Srgrimes passargin = *(++argv); 1421541Srgrimes } else if (strcmp(*argv, "-keyform") == 0) { 1431541Srgrimes if (--argc < 1) 1441541Srgrimes badarg = 1; 1451541Srgrimes else 1461541Srgrimes keyform = str2fmt(*(++argv)); 1471541Srgrimes# ifndef OPENSSL_NO_ENGINE 1481541Srgrimes } else if (!strcmp(*argv, "-engine")) { 1491541Srgrimes if (--argc < 1) 1501541Srgrimes badarg = 1; 1511541Srgrimes else 1521541Srgrimes engine = *(++argv); 1531541Srgrimes# endif 1541541Srgrimes } else if (!strcmp(*argv, "-pubin")) { 1551541Srgrimes key_type = KEY_PUBKEY; 1561541Srgrimes } else if (!strcmp(*argv, "-certin")) { 1571541Srgrimes key_type = KEY_CERT; 1581541Srgrimes } else if (!strcmp(*argv, "-asn1parse")) 1591541Srgrimes asn1parse = 1; 1601541Srgrimes else if (!strcmp(*argv, "-hexdump")) 1611541Srgrimes hexdump = 1; 1621541Srgrimes else if (!strcmp(*argv, "-raw")) 1631541Srgrimes pad = RSA_NO_PADDING; 1641541Srgrimes else if (!strcmp(*argv, "-oaep")) 1651541Srgrimes pad = RSA_PKCS1_OAEP_PADDING; 1661541Srgrimes else if (!strcmp(*argv, "-ssl")) 1671541Srgrimes pad = RSA_SSLV23_PADDING; 1681541Srgrimes else if (!strcmp(*argv, "-pkcs")) 1691541Srgrimes pad = RSA_PKCS1_PADDING; 1701541Srgrimes else if (!strcmp(*argv, "-x931")) 1711541Srgrimes pad = RSA_X931_PADDING; 1721541Srgrimes else if (!strcmp(*argv, "-sign")) { 1731541Srgrimes rsa_mode = RSA_SIGN; 1741541Srgrimes need_priv = 1; 1751541Srgrimes } else if (!strcmp(*argv, "-verify")) 1761541Srgrimes rsa_mode = RSA_VERIFY; 1771541Srgrimes else if (!strcmp(*argv, "-rev")) 1781541Srgrimes rev = 1; 1791541Srgrimes else if (!strcmp(*argv, "-encrypt")) 1801541Srgrimes rsa_mode = RSA_ENCRYPT; 1811541Srgrimes else if (!strcmp(*argv, "-decrypt")) { 1821541Srgrimes rsa_mode = RSA_DECRYPT; 1831541Srgrimes need_priv = 1; 1841541Srgrimes } else 1851541Srgrimes badarg = 1; 1861541Srgrimes if (badarg) { 1871541Srgrimes usage(); 1881541Srgrimes goto end; 1891541Srgrimes } 1901541Srgrimes argc--; 1911541Srgrimes argv++; 1921541Srgrimes } 1931541Srgrimes 1941541Srgrimes if (need_priv && (key_type != KEY_PRIVKEY)) { 1951541Srgrimes BIO_printf(bio_err, "A private key is needed for this operation\n"); 1961541Srgrimes goto end; 1971541Srgrimes } 1981541Srgrimes# ifndef OPENSSL_NO_ENGINE 1991541Srgrimes e = setup_engine(bio_err, engine, 0); 2001541Srgrimes# endif 2011541Srgrimes if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 2021541Srgrimes BIO_printf(bio_err, "Error getting password\n"); 2031541Srgrimes goto end; 2041541Srgrimes } 2051541Srgrimes 2061541Srgrimes/* FIXME: seed PRNG only if needed */ 2071541Srgrimes app_RAND_load_file(NULL, bio_err, 0); 2081541Srgrimes 2091541Srgrimes switch (key_type) { 2101541Srgrimes case KEY_PRIVKEY: 2111541Srgrimes pkey = load_key(bio_err, keyfile, keyform, 0, 2121541Srgrimes passin, e, "Private Key"); 2131541Srgrimes break; 2141541Srgrimes 2151541Srgrimes case KEY_PUBKEY: 2161541Srgrimes pkey = load_pubkey(bio_err, keyfile, keyform, 0, 2171541Srgrimes NULL, e, "Public Key"); 2181541Srgrimes break; 2191541Srgrimes 2201541Srgrimes case KEY_CERT: 2211541Srgrimes x = load_cert(bio_err, keyfile, keyform, NULL, e, "Certificate"); 2221541Srgrimes if (x) { 2231541Srgrimes pkey = X509_get_pubkey(x); 2241541Srgrimes X509_free(x); 2251541Srgrimes } 2261541Srgrimes break; 2271541Srgrimes } 2281541Srgrimes 2291541Srgrimes if (!pkey) { 2301541Srgrimes return 1; 2311541Srgrimes } 2321541Srgrimes 2331541Srgrimes rsa = EVP_PKEY_get1_RSA(pkey); 2341541Srgrimes EVP_PKEY_free(pkey); 2351541Srgrimes 2361541Srgrimes if (!rsa) { 2371541Srgrimes BIO_printf(bio_err, "Error getting RSA key\n"); 2381541Srgrimes ERR_print_errors(bio_err); 2391541Srgrimes goto end; 2401541Srgrimes } 2411541Srgrimes 2421541Srgrimes if (infile) { 2431541Srgrimes if (!(in = BIO_new_file(infile, "rb"))) { 2441541Srgrimes BIO_printf(bio_err, "Error Reading Input File\n"); 2451541Srgrimes ERR_print_errors(bio_err); 2461541Srgrimes goto end; 2471541Srgrimes } 2481541Srgrimes } else 2491541Srgrimes in = BIO_new_fp(stdin, BIO_NOCLOSE); 2501541Srgrimes 2511541Srgrimes if (outfile) { 2521541Srgrimes if (!(out = BIO_new_file(outfile, "wb"))) { 2531541Srgrimes BIO_printf(bio_err, "Error Reading Output File\n"); 2541541Srgrimes ERR_print_errors(bio_err); 2551541Srgrimes goto end; 2561541Srgrimes } 2571541Srgrimes } else { 2581541Srgrimes out = BIO_new_fp(stdout, BIO_NOCLOSE); 2591541Srgrimes# ifdef OPENSSL_SYS_VMS 2601541Srgrimes { 2611541Srgrimes BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 2621541Srgrimes out = BIO_push(tmpbio, out); 2631541Srgrimes } 2641541Srgrimes# endif 2651541Srgrimes } 2661541Srgrimes 2671541Srgrimes keysize = RSA_size(rsa); 2681541Srgrimes 2691541Srgrimes rsa_in = OPENSSL_malloc(keysize * 2); 2701541Srgrimes rsa_out = OPENSSL_malloc(keysize); 2711541Srgrimes 2721541Srgrimes /* Read the input data */ 2731541Srgrimes rsa_inlen = BIO_read(in, rsa_in, keysize * 2); 2741541Srgrimes if (rsa_inlen <= 0) { 2751541Srgrimes BIO_printf(bio_err, "Error reading input Data\n"); 2761541Srgrimes exit(1); 2771541Srgrimes } 2781541Srgrimes if (rev) { 2791541Srgrimes int i; 2801541Srgrimes unsigned char ctmp; 2811541Srgrimes for (i = 0; i < rsa_inlen / 2; i++) { 2821541Srgrimes ctmp = rsa_in[i]; 2831541Srgrimes rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; 2841541Srgrimes rsa_in[rsa_inlen - 1 - i] = ctmp; 2851541Srgrimes } 2861541Srgrimes } 2871541Srgrimes switch (rsa_mode) { 2881541Srgrimes 2891541Srgrimes case RSA_VERIFY: 2901541Srgrimes rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 2911541Srgrimes break; 2921541Srgrimes 2931541Srgrimes case RSA_SIGN: 2941541Srgrimes rsa_outlen = 2951541Srgrimes RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 2961541Srgrimes break; 2971541Srgrimes 2981541Srgrimes case RSA_ENCRYPT: 2991541Srgrimes rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 3001541Srgrimes break; 3011541Srgrimes 3021541Srgrimes case RSA_DECRYPT: 3031541Srgrimes rsa_outlen = 3041541Srgrimes RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); 3051541Srgrimes break; 3061541Srgrimes 3071541Srgrimes } 3081541Srgrimes 3091541Srgrimes if (rsa_outlen <= 0) { 3101541Srgrimes BIO_printf(bio_err, "RSA operation error\n"); 3111541Srgrimes ERR_print_errors(bio_err); 3121541Srgrimes goto end; 3131541Srgrimes } 3141541Srgrimes ret = 0; 3151541Srgrimes if (asn1parse) { 3161541Srgrimes if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { 3171541Srgrimes ERR_print_errors(bio_err); 3181541Srgrimes } 3191541Srgrimes } else if (hexdump) 3201541Srgrimes BIO_dump(out, (char *)rsa_out, rsa_outlen); 3211541Srgrimes else 3221541Srgrimes BIO_write(out, rsa_out, rsa_outlen); 3231541Srgrimes end: 3241541Srgrimes RSA_free(rsa); 3251541Srgrimes BIO_free(in); 3261541Srgrimes BIO_free_all(out); 3271541Srgrimes if (rsa_in) 3281541Srgrimes OPENSSL_free(rsa_in); 3291541Srgrimes if (rsa_out) 3301541Srgrimes OPENSSL_free(rsa_out); 3311541Srgrimes if (passin) 3321541Srgrimes OPENSSL_free(passin); 3331541Srgrimes return ret; 3341541Srgrimes} 3351541Srgrimes 3361541Srgrimesstatic void usage() 3371541Srgrimes{ 3381541Srgrimes BIO_printf(bio_err, "Usage: rsautl [options]\n"); 3391541Srgrimes BIO_printf(bio_err, "-in file input file\n"); 3401541Srgrimes BIO_printf(bio_err, "-out file output file\n"); 3411541Srgrimes BIO_printf(bio_err, "-inkey file input key\n"); 3421541Srgrimes BIO_printf(bio_err, "-keyform arg private key format - default PEM\n"); 3431541Srgrimes BIO_printf(bio_err, "-pubin input is an RSA public\n"); 3441541Srgrimes BIO_printf(bio_err, 3451541Srgrimes "-certin input is a certificate carrying an RSA public key\n"); 3461541Srgrimes BIO_printf(bio_err, "-ssl use SSL v2 padding\n"); 3471541Srgrimes BIO_printf(bio_err, "-raw use no padding\n"); 3481541Srgrimes BIO_printf(bio_err, 3491541Srgrimes "-pkcs use PKCS#1 v1.5 padding (default)\n"); 3501541Srgrimes BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n"); 3511541Srgrimes BIO_printf(bio_err, "-sign sign with private key\n"); 3521541Srgrimes BIO_printf(bio_err, "-verify verify with public key\n"); 3531541Srgrimes BIO_printf(bio_err, "-encrypt encrypt with public key\n"); 3541541Srgrimes BIO_printf(bio_err, "-decrypt decrypt with private key\n"); 3551541Srgrimes BIO_printf(bio_err, "-hexdump hex dump output\n"); 3561541Srgrimes# ifndef OPENSSL_NO_ENGINE 3571541Srgrimes BIO_printf(bio_err, 3581541Srgrimes "-engine e use engine e, possibly a hardware device.\n"); 3591541Srgrimes BIO_printf(bio_err, "-passin arg pass phrase source\n"); 3601541Srgrimes# endif 3611541Srgrimes 3621541Srgrimes} 3631541Srgrimes 3641541Srgrimes#endif 3651541Srgrimes