Annotation of src/usr.bin/openssl/rsautl.c, Revision 1.1
1.1 ! jsing 1: /* $OpenBSD: rsautl.c,v 1.24 2014/07/14 00:35:10 deraadt Exp $ */
! 2: /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
! 3: * project 2000.
! 4: */
! 5: /* ====================================================================
! 6: * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: *
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: *
! 15: * 2. Redistributions in binary form must reproduce the above copyright
! 16: * notice, this list of conditions and the following disclaimer in
! 17: * the documentation and/or other materials provided with the
! 18: * distribution.
! 19: *
! 20: * 3. All advertising materials mentioning features or use of this
! 21: * software must display the following acknowledgment:
! 22: * "This product includes software developed by the OpenSSL Project
! 23: * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
! 24: *
! 25: * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
! 26: * endorse or promote products derived from this software without
! 27: * prior written permission. For written permission, please contact
! 28: * licensing@OpenSSL.org.
! 29: *
! 30: * 5. Products derived from this software may not be called "OpenSSL"
! 31: * nor may "OpenSSL" appear in their names without prior written
! 32: * permission of the OpenSSL Project.
! 33: *
! 34: * 6. Redistributions of any form whatsoever must retain the following
! 35: * acknowledgment:
! 36: * "This product includes software developed by the OpenSSL Project
! 37: * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
! 38: *
! 39: * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
! 40: * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 41: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 42: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
! 43: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
! 44: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 45: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
! 46: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 47: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 48: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 49: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
! 50: * OF THE POSSIBILITY OF SUCH DAMAGE.
! 51: * ====================================================================
! 52: *
! 53: * This product includes cryptographic software written by Eric Young
! 54: * (eay@cryptsoft.com). This product includes software written by Tim
! 55: * Hudson (tjh@cryptsoft.com).
! 56: *
! 57: */
! 58:
! 59: #include <openssl/opensslconf.h>
! 60:
! 61:
! 62: #include <string.h>
! 63:
! 64: #include "apps.h"
! 65:
! 66: #include <openssl/err.h>
! 67: #include <openssl/pem.h>
! 68: #include <openssl/rsa.h>
! 69:
! 70: #define RSA_SIGN 1
! 71: #define RSA_VERIFY 2
! 72: #define RSA_ENCRYPT 3
! 73: #define RSA_DECRYPT 4
! 74:
! 75: #define KEY_PRIVKEY 1
! 76: #define KEY_PUBKEY 2
! 77: #define KEY_CERT 3
! 78:
! 79: static void usage(void);
! 80:
! 81: int rsautl_main(int argc, char **);
! 82:
! 83: int
! 84: rsautl_main(int argc, char **argv)
! 85: {
! 86: ENGINE *e = NULL;
! 87: BIO *in = NULL, *out = NULL;
! 88: char *infile = NULL, *outfile = NULL;
! 89: #ifndef OPENSSL_NO_ENGINE
! 90: char *engine = NULL;
! 91: #endif
! 92: char *keyfile = NULL;
! 93: char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
! 94: int keyform = FORMAT_PEM;
! 95: char need_priv = 0, badarg = 0, rev = 0;
! 96: char hexdump = 0, asn1parse = 0;
! 97: X509 *x;
! 98: EVP_PKEY *pkey = NULL;
! 99: RSA *rsa = NULL;
! 100: unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
! 101: char *passargin = NULL, *passin = NULL;
! 102: int rsa_inlen, rsa_outlen = 0;
! 103: int keysize;
! 104:
! 105: int ret = 1;
! 106:
! 107: argc--;
! 108: argv++;
! 109:
! 110: ERR_load_crypto_strings();
! 111: OpenSSL_add_all_algorithms();
! 112: pad = RSA_PKCS1_PADDING;
! 113:
! 114: while (argc >= 1) {
! 115: if (!strcmp(*argv, "-in")) {
! 116: if (--argc < 1)
! 117: badarg = 1;
! 118: else
! 119: infile = *(++argv);
! 120: } else if (!strcmp(*argv, "-out")) {
! 121: if (--argc < 1)
! 122: badarg = 1;
! 123: else
! 124: outfile = *(++argv);
! 125: } else if (!strcmp(*argv, "-inkey")) {
! 126: if (--argc < 1)
! 127: badarg = 1;
! 128: else
! 129: keyfile = *(++argv);
! 130: } else if (!strcmp(*argv, "-passin")) {
! 131: if (--argc < 1)
! 132: badarg = 1;
! 133: else
! 134: passargin = *(++argv);
! 135: } else if (strcmp(*argv, "-keyform") == 0) {
! 136: if (--argc < 1)
! 137: badarg = 1;
! 138: else
! 139: keyform = str2fmt(*(++argv));
! 140: #ifndef OPENSSL_NO_ENGINE
! 141: } else if (!strcmp(*argv, "-engine")) {
! 142: if (--argc < 1)
! 143: badarg = 1;
! 144: else
! 145: engine = *(++argv);
! 146: #endif
! 147: } else if (!strcmp(*argv, "-pubin")) {
! 148: key_type = KEY_PUBKEY;
! 149: } else if (!strcmp(*argv, "-certin")) {
! 150: key_type = KEY_CERT;
! 151: } else if (!strcmp(*argv, "-asn1parse"))
! 152: asn1parse = 1;
! 153: else if (!strcmp(*argv, "-hexdump"))
! 154: hexdump = 1;
! 155: else if (!strcmp(*argv, "-raw"))
! 156: pad = RSA_NO_PADDING;
! 157: else if (!strcmp(*argv, "-oaep"))
! 158: pad = RSA_PKCS1_OAEP_PADDING;
! 159: else if (!strcmp(*argv, "-ssl"))
! 160: pad = RSA_SSLV23_PADDING;
! 161: else if (!strcmp(*argv, "-pkcs"))
! 162: pad = RSA_PKCS1_PADDING;
! 163: else if (!strcmp(*argv, "-x931"))
! 164: pad = RSA_X931_PADDING;
! 165: else if (!strcmp(*argv, "-sign")) {
! 166: rsa_mode = RSA_SIGN;
! 167: need_priv = 1;
! 168: } else if (!strcmp(*argv, "-verify"))
! 169: rsa_mode = RSA_VERIFY;
! 170: else if (!strcmp(*argv, "-rev"))
! 171: rev = 1;
! 172: else if (!strcmp(*argv, "-encrypt"))
! 173: rsa_mode = RSA_ENCRYPT;
! 174: else if (!strcmp(*argv, "-decrypt")) {
! 175: rsa_mode = RSA_DECRYPT;
! 176: need_priv = 1;
! 177: } else
! 178: badarg = 1;
! 179: if (badarg) {
! 180: usage();
! 181: goto end;
! 182: }
! 183: argc--;
! 184: argv++;
! 185: }
! 186:
! 187: if (need_priv && (key_type != KEY_PRIVKEY)) {
! 188: BIO_printf(bio_err, "A private key is needed for this operation\n");
! 189: goto end;
! 190: }
! 191: #ifndef OPENSSL_NO_ENGINE
! 192: e = setup_engine(bio_err, engine, 0);
! 193: #endif
! 194: if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
! 195: BIO_printf(bio_err, "Error getting password\n");
! 196: goto end;
! 197: }
! 198:
! 199: switch (key_type) {
! 200: case KEY_PRIVKEY:
! 201: pkey = load_key(bio_err, keyfile, keyform, 0,
! 202: passin, e, "Private Key");
! 203: break;
! 204:
! 205: case KEY_PUBKEY:
! 206: pkey = load_pubkey(bio_err, keyfile, keyform, 0,
! 207: NULL, e, "Public Key");
! 208: break;
! 209:
! 210: case KEY_CERT:
! 211: x = load_cert(bio_err, keyfile, keyform,
! 212: NULL, e, "Certificate");
! 213: if (x) {
! 214: pkey = X509_get_pubkey(x);
! 215: X509_free(x);
! 216: }
! 217: break;
! 218: }
! 219:
! 220: if (!pkey) {
! 221: return 1;
! 222: }
! 223: rsa = EVP_PKEY_get1_RSA(pkey);
! 224: EVP_PKEY_free(pkey);
! 225:
! 226: if (!rsa) {
! 227: BIO_printf(bio_err, "Error getting RSA key\n");
! 228: ERR_print_errors(bio_err);
! 229: goto end;
! 230: }
! 231: if (infile) {
! 232: if (!(in = BIO_new_file(infile, "rb"))) {
! 233: BIO_printf(bio_err, "Error Reading Input File\n");
! 234: ERR_print_errors(bio_err);
! 235: goto end;
! 236: }
! 237: } else
! 238: in = BIO_new_fp(stdin, BIO_NOCLOSE);
! 239:
! 240: if (outfile) {
! 241: if (!(out = BIO_new_file(outfile, "wb"))) {
! 242: BIO_printf(bio_err, "Error Reading Output File\n");
! 243: ERR_print_errors(bio_err);
! 244: goto end;
! 245: }
! 246: } else {
! 247: out = BIO_new_fp(stdout, BIO_NOCLOSE);
! 248: }
! 249:
! 250: keysize = RSA_size(rsa);
! 251:
! 252: rsa_in = reallocarray(NULL, keysize, 2);
! 253: rsa_out = malloc(keysize);
! 254:
! 255: /* Read the input data */
! 256: rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
! 257: if (rsa_inlen <= 0) {
! 258: BIO_printf(bio_err, "Error reading input Data\n");
! 259: exit(1);
! 260: }
! 261: if (rev) {
! 262: int i;
! 263: unsigned char ctmp;
! 264: for (i = 0; i < rsa_inlen / 2; i++) {
! 265: ctmp = rsa_in[i];
! 266: rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
! 267: rsa_in[rsa_inlen - 1 - i] = ctmp;
! 268: }
! 269: }
! 270: switch (rsa_mode) {
! 271:
! 272: case RSA_VERIFY:
! 273: rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
! 274: break;
! 275:
! 276: case RSA_SIGN:
! 277: rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
! 278: break;
! 279:
! 280: case RSA_ENCRYPT:
! 281: rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
! 282: break;
! 283:
! 284: case RSA_DECRYPT:
! 285: rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
! 286: break;
! 287:
! 288: }
! 289:
! 290: if (rsa_outlen <= 0) {
! 291: BIO_printf(bio_err, "RSA operation error\n");
! 292: ERR_print_errors(bio_err);
! 293: goto end;
! 294: }
! 295: ret = 0;
! 296: if (asn1parse) {
! 297: if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
! 298: ERR_print_errors(bio_err);
! 299: }
! 300: } else if (hexdump)
! 301: BIO_dump(out, (char *) rsa_out, rsa_outlen);
! 302: else
! 303: BIO_write(out, rsa_out, rsa_outlen);
! 304:
! 305: end:
! 306: RSA_free(rsa);
! 307: BIO_free(in);
! 308: BIO_free_all(out);
! 309: free(rsa_in);
! 310: free(rsa_out);
! 311: free(passin);
! 312:
! 313: return ret;
! 314: }
! 315:
! 316: static void
! 317: usage()
! 318: {
! 319: BIO_printf(bio_err, "Usage: rsautl [options]\n");
! 320: BIO_printf(bio_err, "-in file input file\n");
! 321: BIO_printf(bio_err, "-out file output file\n");
! 322: BIO_printf(bio_err, "-inkey file input key\n");
! 323: BIO_printf(bio_err, "-keyform arg private key format - default PEM\n");
! 324: BIO_printf(bio_err, "-pubin input is an RSA public\n");
! 325: BIO_printf(bio_err, "-certin input is a certificate carrying an RSA public key\n");
! 326: BIO_printf(bio_err, "-ssl use SSL v2 padding\n");
! 327: BIO_printf(bio_err, "-raw use no padding\n");
! 328: BIO_printf(bio_err, "-pkcs use PKCS#1 v1.5 padding (default)\n");
! 329: BIO_printf(bio_err, "-oaep use PKCS#1 OAEP\n");
! 330: BIO_printf(bio_err, "-sign sign with private key\n");
! 331: BIO_printf(bio_err, "-verify verify with public key\n");
! 332: BIO_printf(bio_err, "-encrypt encrypt with public key\n");
! 333: BIO_printf(bio_err, "-decrypt decrypt with private key\n");
! 334: BIO_printf(bio_err, "-hexdump hex dump output\n");
! 335: #ifndef OPENSSL_NO_ENGINE
! 336: BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
! 337: BIO_printf(bio_err, "-passin arg pass phrase source\n");
! 338: #endif
! 339:
! 340: }
! 341: