1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: rsa.c,v 1.16 2022/01/14 09:26:41 tb Exp $ */ 2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3f5b1c8a1SJohn Marino * All rights reserved. 4f5b1c8a1SJohn Marino * 5f5b1c8a1SJohn Marino * This package is an SSL implementation written 6f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com). 7f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL. 8f5b1c8a1SJohn Marino * 9f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as 10f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions 11f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA, 12f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms 14f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15f5b1c8a1SJohn Marino * 16f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in 17f5b1c8a1SJohn Marino * the code are not to be removed. 18f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution 19f5b1c8a1SJohn Marino * as the author of the parts of the library used. 20f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or 21f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package. 22f5b1c8a1SJohn Marino * 23f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 24f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 25f5b1c8a1SJohn Marino * are met: 26f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright 27f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 28f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 29f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the 30f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution. 31f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software 32f5b1c8a1SJohn Marino * must display the following acknowledgement: 33f5b1c8a1SJohn Marino * "This product includes cryptographic software written by 34f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)" 35f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library 36f5b1c8a1SJohn Marino * being used are not cryptographic related :-). 37f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from 38f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement: 39f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40f5b1c8a1SJohn Marino * 41f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51f5b1c8a1SJohn Marino * SUCH DAMAGE. 52f5b1c8a1SJohn Marino * 53f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or 54f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be 55f5b1c8a1SJohn Marino * copied and put under another distribution licence 56f5b1c8a1SJohn Marino * [including the GNU Public Licence.] 57f5b1c8a1SJohn Marino */ 58f5b1c8a1SJohn Marino 59f5b1c8a1SJohn Marino #include <openssl/opensslconf.h> 60f5b1c8a1SJohn Marino 61f5b1c8a1SJohn Marino #include <stdio.h> 62f5b1c8a1SJohn Marino #include <stdlib.h> 63f5b1c8a1SJohn Marino #include <string.h> 64f5b1c8a1SJohn Marino #include <time.h> 65f5b1c8a1SJohn Marino 66f5b1c8a1SJohn Marino #include "apps.h" 67f5b1c8a1SJohn Marino #include "progs.h" 68f5b1c8a1SJohn Marino 69f5b1c8a1SJohn Marino #include <openssl/bio.h> 70f5b1c8a1SJohn Marino #include <openssl/bn.h> 71f5b1c8a1SJohn Marino #include <openssl/err.h> 72f5b1c8a1SJohn Marino #include <openssl/evp.h> 73f5b1c8a1SJohn Marino #include <openssl/pem.h> 74f5b1c8a1SJohn Marino #include <openssl/rsa.h> 75f5b1c8a1SJohn Marino #include <openssl/x509.h> 76f5b1c8a1SJohn Marino 77f5b1c8a1SJohn Marino static struct { 78f5b1c8a1SJohn Marino int check; 79f5b1c8a1SJohn Marino const EVP_CIPHER *enc; 80f5b1c8a1SJohn Marino char *infile; 81f5b1c8a1SJohn Marino int informat; 82f5b1c8a1SJohn Marino int modulus; 83f5b1c8a1SJohn Marino int noout; 84f5b1c8a1SJohn Marino char *outfile; 85f5b1c8a1SJohn Marino int outformat; 86f5b1c8a1SJohn Marino char *passargin; 87f5b1c8a1SJohn Marino char *passargout; 88f5b1c8a1SJohn Marino int pubin; 89f5b1c8a1SJohn Marino int pubout; 90f5b1c8a1SJohn Marino int pvk_encr; 91f5b1c8a1SJohn Marino int text; 92f5b1c8a1SJohn Marino } rsa_config; 93f5b1c8a1SJohn Marino 94f5b1c8a1SJohn Marino static int 95f5b1c8a1SJohn Marino rsa_opt_cipher(int argc, char **argv, int *argsused) 96f5b1c8a1SJohn Marino { 97f5b1c8a1SJohn Marino char *name = argv[0]; 98f5b1c8a1SJohn Marino 99f5b1c8a1SJohn Marino if (*name++ != '-') 100f5b1c8a1SJohn Marino return (1); 101f5b1c8a1SJohn Marino 102f5b1c8a1SJohn Marino if ((rsa_config.enc = EVP_get_cipherbyname(name)) == NULL) { 103f5b1c8a1SJohn Marino fprintf(stderr, "Invalid cipher '%s'\n", name); 104f5b1c8a1SJohn Marino return (1); 105f5b1c8a1SJohn Marino } 106f5b1c8a1SJohn Marino 107f5b1c8a1SJohn Marino *argsused = 1; 108f5b1c8a1SJohn Marino return (0); 109f5b1c8a1SJohn Marino } 110f5b1c8a1SJohn Marino 111cca6fc52SDaniel Fojt static const struct option rsa_options[] = { 112f5b1c8a1SJohn Marino { 113f5b1c8a1SJohn Marino .name = "check", 114f5b1c8a1SJohn Marino .desc = "Check consistency of RSA private key", 115f5b1c8a1SJohn Marino .type = OPTION_FLAG, 116f5b1c8a1SJohn Marino .opt.flag = &rsa_config.check, 117f5b1c8a1SJohn Marino }, 118f5b1c8a1SJohn Marino { 119f5b1c8a1SJohn Marino .name = "in", 120f5b1c8a1SJohn Marino .argname = "file", 121f5b1c8a1SJohn Marino .desc = "Input file (default stdin)", 122f5b1c8a1SJohn Marino .type = OPTION_ARG, 123f5b1c8a1SJohn Marino .opt.arg = &rsa_config.infile, 124f5b1c8a1SJohn Marino }, 125f5b1c8a1SJohn Marino { 126f5b1c8a1SJohn Marino .name = "inform", 127f5b1c8a1SJohn Marino .argname = "format", 128f5b1c8a1SJohn Marino .desc = "Input format (DER, NET or PEM (default))", 129f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 130f5b1c8a1SJohn Marino .opt.value = &rsa_config.informat, 131f5b1c8a1SJohn Marino }, 132f5b1c8a1SJohn Marino { 133f5b1c8a1SJohn Marino .name = "modulus", 134f5b1c8a1SJohn Marino .desc = "Print the RSA key modulus", 135f5b1c8a1SJohn Marino .type = OPTION_FLAG, 136f5b1c8a1SJohn Marino .opt.flag = &rsa_config.modulus, 137f5b1c8a1SJohn Marino }, 138f5b1c8a1SJohn Marino { 139f5b1c8a1SJohn Marino .name = "noout", 140f5b1c8a1SJohn Marino .desc = "Do not print encoded version of the key", 141f5b1c8a1SJohn Marino .type = OPTION_FLAG, 142f5b1c8a1SJohn Marino .opt.flag = &rsa_config.noout, 143f5b1c8a1SJohn Marino }, 144f5b1c8a1SJohn Marino { 145f5b1c8a1SJohn Marino .name = "out", 146f5b1c8a1SJohn Marino .argname = "file", 147f5b1c8a1SJohn Marino .desc = "Output file (default stdout)", 148f5b1c8a1SJohn Marino .type = OPTION_ARG, 149f5b1c8a1SJohn Marino .opt.arg = &rsa_config.outfile, 150f5b1c8a1SJohn Marino }, 151f5b1c8a1SJohn Marino { 152f5b1c8a1SJohn Marino .name = "outform", 153f5b1c8a1SJohn Marino .argname = "format", 154f5b1c8a1SJohn Marino .desc = "Output format (DER, NET or PEM (default PEM))", 155f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 156f5b1c8a1SJohn Marino .opt.value = &rsa_config.outformat, 157f5b1c8a1SJohn Marino }, 158f5b1c8a1SJohn Marino { 159f5b1c8a1SJohn Marino .name = "passin", 160f5b1c8a1SJohn Marino .argname = "src", 161f5b1c8a1SJohn Marino .desc = "Input file passphrase source", 162f5b1c8a1SJohn Marino .type = OPTION_ARG, 163f5b1c8a1SJohn Marino .opt.arg = &rsa_config.passargin, 164f5b1c8a1SJohn Marino }, 165f5b1c8a1SJohn Marino { 166f5b1c8a1SJohn Marino .name = "passout", 167f5b1c8a1SJohn Marino .argname = "src", 168f5b1c8a1SJohn Marino .desc = "Output file passphrase source", 169f5b1c8a1SJohn Marino .type = OPTION_ARG, 170f5b1c8a1SJohn Marino .opt.arg = &rsa_config.passargout, 171f5b1c8a1SJohn Marino }, 172f5b1c8a1SJohn Marino { 173f5b1c8a1SJohn Marino .name = "pubin", 174f5b1c8a1SJohn Marino .desc = "Expect a public key (default private key)", 175f5b1c8a1SJohn Marino .type = OPTION_VALUE, 176f5b1c8a1SJohn Marino .value = 1, 177f5b1c8a1SJohn Marino .opt.value = &rsa_config.pubin, 178f5b1c8a1SJohn Marino }, 179f5b1c8a1SJohn Marino { 180f5b1c8a1SJohn Marino .name = "pubout", 181f5b1c8a1SJohn Marino .desc = "Output a public key (default private key)", 182f5b1c8a1SJohn Marino .type = OPTION_VALUE, 183f5b1c8a1SJohn Marino .value = 1, 184f5b1c8a1SJohn Marino .opt.value = &rsa_config.pubout, 185f5b1c8a1SJohn Marino }, 186f5b1c8a1SJohn Marino { 187f5b1c8a1SJohn Marino .name = "pvk-none", 188f5b1c8a1SJohn Marino .type = OPTION_VALUE, 189f5b1c8a1SJohn Marino .value = 0, 190f5b1c8a1SJohn Marino .opt.value = &rsa_config.pvk_encr, 191f5b1c8a1SJohn Marino }, 192f5b1c8a1SJohn Marino { 193f5b1c8a1SJohn Marino .name = "pvk-strong", 194f5b1c8a1SJohn Marino .type = OPTION_VALUE, 195f5b1c8a1SJohn Marino .value = 2, 196f5b1c8a1SJohn Marino .opt.value = &rsa_config.pvk_encr, 197f5b1c8a1SJohn Marino }, 198f5b1c8a1SJohn Marino { 199f5b1c8a1SJohn Marino .name = "pvk-weak", 200f5b1c8a1SJohn Marino .type = OPTION_VALUE, 201f5b1c8a1SJohn Marino .value = 1, 202f5b1c8a1SJohn Marino .opt.value = &rsa_config.pvk_encr, 203f5b1c8a1SJohn Marino }, 204f5b1c8a1SJohn Marino { 205f5b1c8a1SJohn Marino .name = "RSAPublicKey_in", 206f5b1c8a1SJohn Marino .type = OPTION_VALUE, 207f5b1c8a1SJohn Marino .value = 2, 208f5b1c8a1SJohn Marino .opt.value = &rsa_config.pubin, 209f5b1c8a1SJohn Marino }, 210f5b1c8a1SJohn Marino { 211f5b1c8a1SJohn Marino .name = "RSAPublicKey_out", 212f5b1c8a1SJohn Marino .type = OPTION_VALUE, 213f5b1c8a1SJohn Marino .value = 2, 214f5b1c8a1SJohn Marino .opt.value = &rsa_config.pubout, 215f5b1c8a1SJohn Marino }, 216f5b1c8a1SJohn Marino { 217f5b1c8a1SJohn Marino .name = "text", 218f5b1c8a1SJohn Marino .desc = "Print in plain text in addition to encoded", 219f5b1c8a1SJohn Marino .type = OPTION_FLAG, 220f5b1c8a1SJohn Marino .opt.flag = &rsa_config.text, 221f5b1c8a1SJohn Marino }, 222f5b1c8a1SJohn Marino { 223f5b1c8a1SJohn Marino .name = NULL, 224f5b1c8a1SJohn Marino .type = OPTION_ARGV_FUNC, 225f5b1c8a1SJohn Marino .opt.argvfunc = rsa_opt_cipher, 226f5b1c8a1SJohn Marino }, 227f5b1c8a1SJohn Marino { NULL } 228f5b1c8a1SJohn Marino }; 229f5b1c8a1SJohn Marino 230f5b1c8a1SJohn Marino static void 231f5b1c8a1SJohn Marino rsa_usage() 232f5b1c8a1SJohn Marino { 23372c33676SMaxim Ag int n = 0; 23472c33676SMaxim Ag 235f5b1c8a1SJohn Marino fprintf(stderr, 236f5b1c8a1SJohn Marino "usage: rsa [-ciphername] [-check] [-in file] " 237f5b1c8a1SJohn Marino "[-inform fmt]\n" 238f5b1c8a1SJohn Marino " [-modulus] [-noout] [-out file] [-outform fmt] " 239f5b1c8a1SJohn Marino "[-passin src]\n" 240*de0e0e4dSAntonio Huete Jimenez " [-passout src] [-pubin] [-pubout] [-text]\n\n"); 241f5b1c8a1SJohn Marino options_usage(rsa_options); 242f5b1c8a1SJohn Marino fprintf(stderr, "\n"); 243f5b1c8a1SJohn Marino 244f5b1c8a1SJohn Marino fprintf(stderr, "Valid ciphername values:\n\n"); 24572c33676SMaxim Ag OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n); 246f5b1c8a1SJohn Marino fprintf(stderr, "\n"); 247f5b1c8a1SJohn Marino } 248f5b1c8a1SJohn Marino 249f5b1c8a1SJohn Marino int 250f5b1c8a1SJohn Marino rsa_main(int argc, char **argv) 251f5b1c8a1SJohn Marino { 252f5b1c8a1SJohn Marino int ret = 1; 253f5b1c8a1SJohn Marino RSA *rsa = NULL; 254f5b1c8a1SJohn Marino int i; 255f5b1c8a1SJohn Marino BIO *out = NULL; 256f5b1c8a1SJohn Marino char *passin = NULL, *passout = NULL; 257f5b1c8a1SJohn Marino 258f5b1c8a1SJohn Marino if (single_execution) { 25972c33676SMaxim Ag if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { 260f5b1c8a1SJohn Marino perror("pledge"); 261f5b1c8a1SJohn Marino exit(1); 262f5b1c8a1SJohn Marino } 263f5b1c8a1SJohn Marino } 264f5b1c8a1SJohn Marino 265f5b1c8a1SJohn Marino memset(&rsa_config, 0, sizeof(rsa_config)); 266f5b1c8a1SJohn Marino rsa_config.pvk_encr = 2; 267f5b1c8a1SJohn Marino rsa_config.informat = FORMAT_PEM; 268f5b1c8a1SJohn Marino rsa_config.outformat = FORMAT_PEM; 269f5b1c8a1SJohn Marino 270f5b1c8a1SJohn Marino if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) { 271f5b1c8a1SJohn Marino rsa_usage(); 272f5b1c8a1SJohn Marino goto end; 273f5b1c8a1SJohn Marino } 274f5b1c8a1SJohn Marino 275f5b1c8a1SJohn Marino if (!app_passwd(bio_err, rsa_config.passargin, rsa_config.passargout, 276f5b1c8a1SJohn Marino &passin, &passout)) { 277f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error getting passwords\n"); 278f5b1c8a1SJohn Marino goto end; 279f5b1c8a1SJohn Marino } 280f5b1c8a1SJohn Marino if (rsa_config.check && rsa_config.pubin) { 281f5b1c8a1SJohn Marino BIO_printf(bio_err, "Only private keys can be checked\n"); 282f5b1c8a1SJohn Marino goto end; 283f5b1c8a1SJohn Marino } 284f5b1c8a1SJohn Marino out = BIO_new(BIO_s_file()); 285f5b1c8a1SJohn Marino 286f5b1c8a1SJohn Marino { 287f5b1c8a1SJohn Marino EVP_PKEY *pkey; 288f5b1c8a1SJohn Marino 289f5b1c8a1SJohn Marino if (rsa_config.pubin) { 290f5b1c8a1SJohn Marino int tmpformat = -1; 291f5b1c8a1SJohn Marino if (rsa_config.pubin == 2) { 292f5b1c8a1SJohn Marino if (rsa_config.informat == FORMAT_PEM) 293f5b1c8a1SJohn Marino tmpformat = FORMAT_PEMRSA; 294f5b1c8a1SJohn Marino else if (rsa_config.informat == FORMAT_ASN1) 295f5b1c8a1SJohn Marino tmpformat = FORMAT_ASN1RSA; 296*de0e0e4dSAntonio Huete Jimenez } else 297f5b1c8a1SJohn Marino tmpformat = rsa_config.informat; 298f5b1c8a1SJohn Marino 299f5b1c8a1SJohn Marino pkey = load_pubkey(bio_err, rsa_config.infile, 300f5b1c8a1SJohn Marino tmpformat, 1, passin, "Public Key"); 301f5b1c8a1SJohn Marino } else 302f5b1c8a1SJohn Marino pkey = load_key(bio_err, rsa_config.infile, 303*de0e0e4dSAntonio Huete Jimenez rsa_config.informat, 1, passin, "Private Key"); 304f5b1c8a1SJohn Marino 305f5b1c8a1SJohn Marino if (pkey != NULL) 306f5b1c8a1SJohn Marino rsa = EVP_PKEY_get1_RSA(pkey); 307f5b1c8a1SJohn Marino EVP_PKEY_free(pkey); 308f5b1c8a1SJohn Marino } 309f5b1c8a1SJohn Marino 310f5b1c8a1SJohn Marino if (rsa == NULL) { 311f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 312f5b1c8a1SJohn Marino goto end; 313f5b1c8a1SJohn Marino } 314f5b1c8a1SJohn Marino if (rsa_config.outfile == NULL) { 315f5b1c8a1SJohn Marino BIO_set_fp(out, stdout, BIO_NOCLOSE); 316f5b1c8a1SJohn Marino } else { 317f5b1c8a1SJohn Marino if (BIO_write_filename(out, rsa_config.outfile) <= 0) { 318f5b1c8a1SJohn Marino perror(rsa_config.outfile); 319f5b1c8a1SJohn Marino goto end; 320f5b1c8a1SJohn Marino } 321f5b1c8a1SJohn Marino } 322f5b1c8a1SJohn Marino 323f5b1c8a1SJohn Marino if (rsa_config.text) 324f5b1c8a1SJohn Marino if (!RSA_print(out, rsa, 0)) { 325f5b1c8a1SJohn Marino perror(rsa_config.outfile); 326f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 327f5b1c8a1SJohn Marino goto end; 328f5b1c8a1SJohn Marino } 329f5b1c8a1SJohn Marino if (rsa_config.modulus) { 330f5b1c8a1SJohn Marino BIO_printf(out, "Modulus="); 331*de0e0e4dSAntonio Huete Jimenez BN_print(out, RSA_get0_n(rsa)); 332f5b1c8a1SJohn Marino BIO_printf(out, "\n"); 333f5b1c8a1SJohn Marino } 334f5b1c8a1SJohn Marino if (rsa_config.check) { 335f5b1c8a1SJohn Marino int r = RSA_check_key(rsa); 336f5b1c8a1SJohn Marino 337f5b1c8a1SJohn Marino if (r == 1) 338f5b1c8a1SJohn Marino BIO_printf(out, "RSA key ok\n"); 339f5b1c8a1SJohn Marino else if (r == 0) { 340f5b1c8a1SJohn Marino unsigned long err; 341f5b1c8a1SJohn Marino 342f5b1c8a1SJohn Marino while ((err = ERR_peek_error()) != 0 && 343f5b1c8a1SJohn Marino ERR_GET_LIB(err) == ERR_LIB_RSA && 344f5b1c8a1SJohn Marino ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && 345f5b1c8a1SJohn Marino ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { 346f5b1c8a1SJohn Marino BIO_printf(out, "RSA key error: %s\n", 347f5b1c8a1SJohn Marino ERR_reason_error_string(err)); 348f5b1c8a1SJohn Marino ERR_get_error(); /* remove e from error 349f5b1c8a1SJohn Marino * stack */ 350f5b1c8a1SJohn Marino } 351f5b1c8a1SJohn Marino } 352f5b1c8a1SJohn Marino if (r == -1 || ERR_peek_error() != 0) { /* should happen only if 353f5b1c8a1SJohn Marino * r == -1 */ 354f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 355f5b1c8a1SJohn Marino goto end; 356f5b1c8a1SJohn Marino } 357f5b1c8a1SJohn Marino } 358f5b1c8a1SJohn Marino if (rsa_config.noout) { 359f5b1c8a1SJohn Marino ret = 0; 360f5b1c8a1SJohn Marino goto end; 361f5b1c8a1SJohn Marino } 362f5b1c8a1SJohn Marino BIO_printf(bio_err, "writing RSA key\n"); 363f5b1c8a1SJohn Marino if (rsa_config.outformat == FORMAT_ASN1) { 364f5b1c8a1SJohn Marino if (rsa_config.pubout || rsa_config.pubin) { 365f5b1c8a1SJohn Marino if (rsa_config.pubout == 2) 366f5b1c8a1SJohn Marino i = i2d_RSAPublicKey_bio(out, rsa); 367f5b1c8a1SJohn Marino else 368f5b1c8a1SJohn Marino i = i2d_RSA_PUBKEY_bio(out, rsa); 369f5b1c8a1SJohn Marino } else 370f5b1c8a1SJohn Marino i = i2d_RSAPrivateKey_bio(out, rsa); 371*de0e0e4dSAntonio Huete Jimenez } else if (rsa_config.outformat == FORMAT_PEM) { 372f5b1c8a1SJohn Marino if (rsa_config.pubout || rsa_config.pubin) { 373f5b1c8a1SJohn Marino if (rsa_config.pubout == 2) 374f5b1c8a1SJohn Marino i = PEM_write_bio_RSAPublicKey(out, rsa); 375f5b1c8a1SJohn Marino else 376f5b1c8a1SJohn Marino i = PEM_write_bio_RSA_PUBKEY(out, rsa); 377f5b1c8a1SJohn Marino } else 378f5b1c8a1SJohn Marino i = PEM_write_bio_RSAPrivateKey(out, rsa, 379f5b1c8a1SJohn Marino rsa_config.enc, NULL, 0, NULL, passout); 380f5b1c8a1SJohn Marino #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) 381f5b1c8a1SJohn Marino } else if (rsa_config.outformat == FORMAT_MSBLOB || 382f5b1c8a1SJohn Marino rsa_config.outformat == FORMAT_PVK) { 383f5b1c8a1SJohn Marino EVP_PKEY *pk; 384f5b1c8a1SJohn Marino pk = EVP_PKEY_new(); 385f5b1c8a1SJohn Marino EVP_PKEY_set1_RSA(pk, rsa); 386f5b1c8a1SJohn Marino if (rsa_config.outformat == FORMAT_PVK) 387f5b1c8a1SJohn Marino i = i2b_PVK_bio(out, pk, rsa_config.pvk_encr, 0, 388f5b1c8a1SJohn Marino passout); 389f5b1c8a1SJohn Marino else if (rsa_config.pubin || rsa_config.pubout) 390f5b1c8a1SJohn Marino i = i2b_PublicKey_bio(out, pk); 391f5b1c8a1SJohn Marino else 392f5b1c8a1SJohn Marino i = i2b_PrivateKey_bio(out, pk); 393f5b1c8a1SJohn Marino EVP_PKEY_free(pk); 394f5b1c8a1SJohn Marino #endif 395f5b1c8a1SJohn Marino } else { 396f5b1c8a1SJohn Marino BIO_printf(bio_err, 397f5b1c8a1SJohn Marino "bad output format specified for outfile\n"); 398f5b1c8a1SJohn Marino goto end; 399f5b1c8a1SJohn Marino } 400f5b1c8a1SJohn Marino if (i <= 0) { 401f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to write key\n"); 402f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 403f5b1c8a1SJohn Marino } else 404f5b1c8a1SJohn Marino ret = 0; 405f5b1c8a1SJohn Marino 406f5b1c8a1SJohn Marino end: 407f5b1c8a1SJohn Marino BIO_free_all(out); 408f5b1c8a1SJohn Marino RSA_free(rsa); 409f5b1c8a1SJohn Marino free(passin); 410f5b1c8a1SJohn Marino free(passout); 411f5b1c8a1SJohn Marino 412f5b1c8a1SJohn Marino return (ret); 413f5b1c8a1SJohn Marino } 414