11f13597dSJung-uk Kim /* apps/pkey.c */ 2*6f9291ceSJung-uk Kim /* 3*6f9291ceSJung-uk Kim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4*6f9291ceSJung-uk Kim * 2006 51f13597dSJung-uk Kim */ 61f13597dSJung-uk Kim /* ==================================================================== 71f13597dSJung-uk Kim * Copyright (c) 2006 The OpenSSL Project. All rights reserved. 81f13597dSJung-uk Kim * 91f13597dSJung-uk Kim * Redistribution and use in source and binary forms, with or without 101f13597dSJung-uk Kim * modification, are permitted provided that the following conditions 111f13597dSJung-uk Kim * are met: 121f13597dSJung-uk Kim * 131f13597dSJung-uk Kim * 1. Redistributions of source code must retain the above copyright 141f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer. 151f13597dSJung-uk Kim * 161f13597dSJung-uk Kim * 2. Redistributions in binary form must reproduce the above copyright 171f13597dSJung-uk Kim * notice, this list of conditions and the following disclaimer in 181f13597dSJung-uk Kim * the documentation and/or other materials provided with the 191f13597dSJung-uk Kim * distribution. 201f13597dSJung-uk Kim * 211f13597dSJung-uk Kim * 3. All advertising materials mentioning features or use of this 221f13597dSJung-uk Kim * software must display the following acknowledgment: 231f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 241f13597dSJung-uk Kim * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 251f13597dSJung-uk Kim * 261f13597dSJung-uk Kim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 271f13597dSJung-uk Kim * endorse or promote products derived from this software without 281f13597dSJung-uk Kim * prior written permission. For written permission, please contact 291f13597dSJung-uk Kim * licensing@OpenSSL.org. 301f13597dSJung-uk Kim * 311f13597dSJung-uk Kim * 5. Products derived from this software may not be called "OpenSSL" 321f13597dSJung-uk Kim * nor may "OpenSSL" appear in their names without prior written 331f13597dSJung-uk Kim * permission of the OpenSSL Project. 341f13597dSJung-uk Kim * 351f13597dSJung-uk Kim * 6. Redistributions of any form whatsoever must retain the following 361f13597dSJung-uk Kim * acknowledgment: 371f13597dSJung-uk Kim * "This product includes software developed by the OpenSSL Project 381f13597dSJung-uk Kim * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 391f13597dSJung-uk Kim * 401f13597dSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 411f13597dSJung-uk Kim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 421f13597dSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 431f13597dSJung-uk Kim * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 441f13597dSJung-uk Kim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 451f13597dSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 461f13597dSJung-uk Kim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 471f13597dSJung-uk Kim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 481f13597dSJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 491f13597dSJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 501f13597dSJung-uk Kim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 511f13597dSJung-uk Kim * OF THE POSSIBILITY OF SUCH DAMAGE. 521f13597dSJung-uk Kim * ==================================================================== 531f13597dSJung-uk Kim * 541f13597dSJung-uk Kim * This product includes cryptographic software written by Eric Young 551f13597dSJung-uk Kim * (eay@cryptsoft.com). This product includes software written by Tim 561f13597dSJung-uk Kim * Hudson (tjh@cryptsoft.com). 571f13597dSJung-uk Kim * 581f13597dSJung-uk Kim */ 591f13597dSJung-uk Kim #include <stdio.h> 601f13597dSJung-uk Kim #include <string.h> 611f13597dSJung-uk Kim #include "apps.h" 621f13597dSJung-uk Kim #include <openssl/pem.h> 631f13597dSJung-uk Kim #include <openssl/err.h> 641f13597dSJung-uk Kim #include <openssl/evp.h> 651f13597dSJung-uk Kim 661f13597dSJung-uk Kim #define PROG pkey_main 671f13597dSJung-uk Kim 681f13597dSJung-uk Kim int MAIN(int, char **); 691f13597dSJung-uk Kim 701f13597dSJung-uk Kim int MAIN(int argc, char **argv) 711f13597dSJung-uk Kim { 721f13597dSJung-uk Kim ENGINE *e = NULL; 731f13597dSJung-uk Kim char **args, *infile = NULL, *outfile = NULL; 741f13597dSJung-uk Kim char *passargin = NULL, *passargout = NULL; 751f13597dSJung-uk Kim BIO *in = NULL, *out = NULL; 761f13597dSJung-uk Kim const EVP_CIPHER *cipher = NULL; 771f13597dSJung-uk Kim int informat, outformat; 781f13597dSJung-uk Kim int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0; 791f13597dSJung-uk Kim EVP_PKEY *pkey = NULL; 801f13597dSJung-uk Kim char *passin = NULL, *passout = NULL; 811f13597dSJung-uk Kim int badarg = 0; 821f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE 831f13597dSJung-uk Kim char *engine = NULL; 841f13597dSJung-uk Kim #endif 851f13597dSJung-uk Kim int ret = 1; 861f13597dSJung-uk Kim 871f13597dSJung-uk Kim if (bio_err == NULL) 881f13597dSJung-uk Kim bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 891f13597dSJung-uk Kim 901f13597dSJung-uk Kim if (!load_config(bio_err, NULL)) 911f13597dSJung-uk Kim goto end; 921f13597dSJung-uk Kim 931f13597dSJung-uk Kim informat = FORMAT_PEM; 941f13597dSJung-uk Kim outformat = FORMAT_PEM; 951f13597dSJung-uk Kim 961f13597dSJung-uk Kim ERR_load_crypto_strings(); 971f13597dSJung-uk Kim OpenSSL_add_all_algorithms(); 981f13597dSJung-uk Kim args = argv + 1; 99*6f9291ceSJung-uk Kim while (!badarg && *args && *args[0] == '-') { 100*6f9291ceSJung-uk Kim if (!strcmp(*args, "-inform")) { 101*6f9291ceSJung-uk Kim if (args[1]) { 1021f13597dSJung-uk Kim args++; 1031f13597dSJung-uk Kim informat = str2fmt(*args); 104*6f9291ceSJung-uk Kim } else 105*6f9291ceSJung-uk Kim badarg = 1; 106*6f9291ceSJung-uk Kim } else if (!strcmp(*args, "-outform")) { 107*6f9291ceSJung-uk Kim if (args[1]) { 1081f13597dSJung-uk Kim args++; 1091f13597dSJung-uk Kim outformat = str2fmt(*args); 110*6f9291ceSJung-uk Kim } else 111*6f9291ceSJung-uk Kim badarg = 1; 112*6f9291ceSJung-uk Kim } else if (!strcmp(*args, "-passin")) { 113*6f9291ceSJung-uk Kim if (!args[1]) 114*6f9291ceSJung-uk Kim goto bad; 1151f13597dSJung-uk Kim passargin = *(++args); 116*6f9291ceSJung-uk Kim } else if (!strcmp(*args, "-passout")) { 117*6f9291ceSJung-uk Kim if (!args[1]) 118*6f9291ceSJung-uk Kim goto bad; 1191f13597dSJung-uk Kim passargout = *(++args); 1201f13597dSJung-uk Kim } 1211f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE 122*6f9291ceSJung-uk Kim else if (strcmp(*args, "-engine") == 0) { 123*6f9291ceSJung-uk Kim if (!args[1]) 124*6f9291ceSJung-uk Kim goto bad; 1251f13597dSJung-uk Kim engine = *(++args); 1261f13597dSJung-uk Kim } 1271f13597dSJung-uk Kim #endif 128*6f9291ceSJung-uk Kim else if (!strcmp(*args, "-in")) { 129*6f9291ceSJung-uk Kim if (args[1]) { 1301f13597dSJung-uk Kim args++; 1311f13597dSJung-uk Kim infile = *args; 132*6f9291ceSJung-uk Kim } else 133*6f9291ceSJung-uk Kim badarg = 1; 134*6f9291ceSJung-uk Kim } else if (!strcmp(*args, "-out")) { 135*6f9291ceSJung-uk Kim if (args[1]) { 1361f13597dSJung-uk Kim args++; 1371f13597dSJung-uk Kim outfile = *args; 138*6f9291ceSJung-uk Kim } else 139*6f9291ceSJung-uk Kim badarg = 1; 140*6f9291ceSJung-uk Kim } else if (strcmp(*args, "-pubin") == 0) { 1411f13597dSJung-uk Kim pubin = 1; 1421f13597dSJung-uk Kim pubout = 1; 1431f13597dSJung-uk Kim pubtext = 1; 144*6f9291ceSJung-uk Kim } else if (strcmp(*args, "-pubout") == 0) 1451f13597dSJung-uk Kim pubout = 1; 146*6f9291ceSJung-uk Kim else if (strcmp(*args, "-text_pub") == 0) { 1471f13597dSJung-uk Kim pubtext = 1; 1481f13597dSJung-uk Kim text = 1; 149*6f9291ceSJung-uk Kim } else if (strcmp(*args, "-text") == 0) 1501f13597dSJung-uk Kim text = 1; 1511f13597dSJung-uk Kim else if (strcmp(*args, "-noout") == 0) 1521f13597dSJung-uk Kim noout = 1; 153*6f9291ceSJung-uk Kim else { 1541f13597dSJung-uk Kim cipher = EVP_get_cipherbyname(*args + 1); 155*6f9291ceSJung-uk Kim if (!cipher) { 156*6f9291ceSJung-uk Kim BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); 1571f13597dSJung-uk Kim badarg = 1; 1581f13597dSJung-uk Kim } 1591f13597dSJung-uk Kim } 1601f13597dSJung-uk Kim args++; 1611f13597dSJung-uk Kim } 1621f13597dSJung-uk Kim 163*6f9291ceSJung-uk Kim if (badarg) { 1641f13597dSJung-uk Kim bad: 1651f13597dSJung-uk Kim BIO_printf(bio_err, "Usage pkey [options]\n"); 1661f13597dSJung-uk Kim BIO_printf(bio_err, "where options are\n"); 1671f13597dSJung-uk Kim BIO_printf(bio_err, "-in file input file\n"); 1681f13597dSJung-uk Kim BIO_printf(bio_err, "-inform X input format (DER or PEM)\n"); 169*6f9291ceSJung-uk Kim BIO_printf(bio_err, 170*6f9291ceSJung-uk Kim "-passin arg input file pass phrase source\n"); 1711f13597dSJung-uk Kim BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); 1721f13597dSJung-uk Kim BIO_printf(bio_err, "-out file output file\n"); 173*6f9291ceSJung-uk Kim BIO_printf(bio_err, 174*6f9291ceSJung-uk Kim "-passout arg output file pass phrase source\n"); 1751f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE 176*6f9291ceSJung-uk Kim BIO_printf(bio_err, 177*6f9291ceSJung-uk Kim "-engine e use engine e, possibly a hardware device.\n"); 1781f13597dSJung-uk Kim #endif 1791f13597dSJung-uk Kim return 1; 1801f13597dSJung-uk Kim } 1811f13597dSJung-uk Kim #ifndef OPENSSL_NO_ENGINE 1821f13597dSJung-uk Kim e = setup_engine(bio_err, engine, 0); 1831f13597dSJung-uk Kim #endif 1841f13597dSJung-uk Kim 185*6f9291ceSJung-uk Kim if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 1861f13597dSJung-uk Kim BIO_printf(bio_err, "Error getting passwords\n"); 1871f13597dSJung-uk Kim goto end; 1881f13597dSJung-uk Kim } 1891f13597dSJung-uk Kim 190*6f9291ceSJung-uk Kim if (outfile) { 191*6f9291ceSJung-uk Kim if (!(out = BIO_new_file(outfile, "wb"))) { 192*6f9291ceSJung-uk Kim BIO_printf(bio_err, "Can't open output file %s\n", outfile); 1931f13597dSJung-uk Kim goto end; 1941f13597dSJung-uk Kim } 195*6f9291ceSJung-uk Kim } else { 1961f13597dSJung-uk Kim out = BIO_new_fp(stdout, BIO_NOCLOSE); 1971f13597dSJung-uk Kim #ifdef OPENSSL_SYS_VMS 1981f13597dSJung-uk Kim { 1991f13597dSJung-uk Kim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 2001f13597dSJung-uk Kim out = BIO_push(tmpbio, out); 2011f13597dSJung-uk Kim } 2021f13597dSJung-uk Kim #endif 2031f13597dSJung-uk Kim } 2041f13597dSJung-uk Kim 2051f13597dSJung-uk Kim if (pubin) 2061f13597dSJung-uk Kim pkey = load_pubkey(bio_err, infile, informat, 1, 2071f13597dSJung-uk Kim passin, e, "Public Key"); 2081f13597dSJung-uk Kim else 209*6f9291ceSJung-uk Kim pkey = load_key(bio_err, infile, informat, 1, passin, e, "key"); 2101f13597dSJung-uk Kim if (!pkey) 2111f13597dSJung-uk Kim goto end; 2121f13597dSJung-uk Kim 213*6f9291ceSJung-uk Kim if (!noout) { 214*6f9291ceSJung-uk Kim if (outformat == FORMAT_PEM) { 2151f13597dSJung-uk Kim if (pubout) 2161f13597dSJung-uk Kim PEM_write_bio_PUBKEY(out, pkey); 2171f13597dSJung-uk Kim else 2181f13597dSJung-uk Kim PEM_write_bio_PrivateKey(out, pkey, cipher, 2191f13597dSJung-uk Kim NULL, 0, NULL, passout); 220*6f9291ceSJung-uk Kim } else if (outformat == FORMAT_ASN1) { 2211f13597dSJung-uk Kim if (pubout) 2221f13597dSJung-uk Kim i2d_PUBKEY_bio(out, pkey); 2231f13597dSJung-uk Kim else 2241f13597dSJung-uk Kim i2d_PrivateKey_bio(out, pkey); 225*6f9291ceSJung-uk Kim } else { 2261f13597dSJung-uk Kim BIO_printf(bio_err, "Bad format specified for key\n"); 2271f13597dSJung-uk Kim goto end; 2281f13597dSJung-uk Kim } 2291f13597dSJung-uk Kim 2301f13597dSJung-uk Kim } 2311f13597dSJung-uk Kim 232*6f9291ceSJung-uk Kim if (text) { 2331f13597dSJung-uk Kim if (pubtext) 2341f13597dSJung-uk Kim EVP_PKEY_print_public(out, pkey, 0, NULL); 2351f13597dSJung-uk Kim else 2361f13597dSJung-uk Kim EVP_PKEY_print_private(out, pkey, 0, NULL); 2371f13597dSJung-uk Kim } 2381f13597dSJung-uk Kim 2391f13597dSJung-uk Kim ret = 0; 2401f13597dSJung-uk Kim 2411f13597dSJung-uk Kim end: 2421f13597dSJung-uk Kim EVP_PKEY_free(pkey); 2431f13597dSJung-uk Kim BIO_free_all(out); 2441f13597dSJung-uk Kim BIO_free(in); 2451f13597dSJung-uk Kim if (passin) 2461f13597dSJung-uk Kim OPENSSL_free(passin); 2471f13597dSJung-uk Kim if (passout) 2481f13597dSJung-uk Kim OPENSSL_free(passout); 2491f13597dSJung-uk Kim 2501f13597dSJung-uk Kim return ret; 2511f13597dSJung-uk Kim } 252