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