1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include <stdlib.h> 12e1051a39Sopenharmony_ci#include <string.h> 13e1051a39Sopenharmony_ci#include "apps.h" 14e1051a39Sopenharmony_ci#include "progs.h" 15e1051a39Sopenharmony_ci#include <openssl/pem.h> 16e1051a39Sopenharmony_ci#include <openssl/err.h> 17e1051a39Sopenharmony_ci#include <openssl/evp.h> 18e1051a39Sopenharmony_ci#include <openssl/pkcs12.h> 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_citypedef enum OPTION_choice { 21e1051a39Sopenharmony_ci OPT_COMMON, 22e1051a39Sopenharmony_ci OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT, 23e1051a39Sopenharmony_ci OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT, 24e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCRYPT 25e1051a39Sopenharmony_ci OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P, 26e1051a39Sopenharmony_ci#endif 27e1051a39Sopenharmony_ci OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT, 28e1051a39Sopenharmony_ci OPT_TRADITIONAL, 29e1051a39Sopenharmony_ci OPT_R_ENUM, OPT_PROV_ENUM 30e1051a39Sopenharmony_ci} OPTION_CHOICE; 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ciconst OPTIONS pkcs8_options[] = { 33e1051a39Sopenharmony_ci OPT_SECTION("General"), 34e1051a39Sopenharmony_ci {"help", OPT_HELP, '-', "Display this summary"}, 35e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_ENGINE 36e1051a39Sopenharmony_ci {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, 37e1051a39Sopenharmony_ci#endif 38e1051a39Sopenharmony_ci {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"}, 39e1051a39Sopenharmony_ci {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"}, 40e1051a39Sopenharmony_ci {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"}, 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci OPT_SECTION("Input"), 43e1051a39Sopenharmony_ci {"in", OPT_IN, '<', "Input file"}, 44e1051a39Sopenharmony_ci {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"}, 45e1051a39Sopenharmony_ci {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, 46e1051a39Sopenharmony_ci {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"}, 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_ci OPT_SECTION("Output"), 49e1051a39Sopenharmony_ci {"out", OPT_OUT, '>', "Output file"}, 50e1051a39Sopenharmony_ci {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"}, 51e1051a39Sopenharmony_ci {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"}, 52e1051a39Sopenharmony_ci {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, 53e1051a39Sopenharmony_ci {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"}, 54e1051a39Sopenharmony_ci {"iter", OPT_ITER, 'p', "Specify the iteration count"}, 55e1051a39Sopenharmony_ci {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"}, 56e1051a39Sopenharmony_ci 57e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCRYPT 58e1051a39Sopenharmony_ci OPT_SECTION("Scrypt"), 59e1051a39Sopenharmony_ci {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"}, 60e1051a39Sopenharmony_ci {"scrypt_N", OPT_SCRYPT_N, 's', "Set scrypt N parameter"}, 61e1051a39Sopenharmony_ci {"scrypt_r", OPT_SCRYPT_R, 's', "Set scrypt r parameter"}, 62e1051a39Sopenharmony_ci {"scrypt_p", OPT_SCRYPT_P, 's', "Set scrypt p parameter"}, 63e1051a39Sopenharmony_ci#endif 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci OPT_R_OPTIONS, 66e1051a39Sopenharmony_ci OPT_PROV_OPTIONS, 67e1051a39Sopenharmony_ci {NULL} 68e1051a39Sopenharmony_ci}; 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ciint pkcs8_main(int argc, char **argv) 71e1051a39Sopenharmony_ci{ 72e1051a39Sopenharmony_ci BIO *in = NULL, *out = NULL; 73e1051a39Sopenharmony_ci ENGINE *e = NULL; 74e1051a39Sopenharmony_ci EVP_PKEY *pkey = NULL; 75e1051a39Sopenharmony_ci PKCS8_PRIV_KEY_INFO *p8inf = NULL; 76e1051a39Sopenharmony_ci X509_SIG *p8 = NULL; 77e1051a39Sopenharmony_ci EVP_CIPHER *cipher = NULL; 78e1051a39Sopenharmony_ci char *infile = NULL, *outfile = NULL, *ciphername = NULL; 79e1051a39Sopenharmony_ci char *passinarg = NULL, *passoutarg = NULL, *prog; 80e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_UI_CONSOLE 81e1051a39Sopenharmony_ci char pass[APP_PASS_LEN]; 82e1051a39Sopenharmony_ci#endif 83e1051a39Sopenharmony_ci char *passin = NULL, *passout = NULL, *p8pass = NULL; 84e1051a39Sopenharmony_ci OPTION_CHOICE o; 85e1051a39Sopenharmony_ci int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER; 86e1051a39Sopenharmony_ci int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; 87e1051a39Sopenharmony_ci int private = 0, traditional = 0; 88e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCRYPT 89e1051a39Sopenharmony_ci long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0; 90e1051a39Sopenharmony_ci#endif 91e1051a39Sopenharmony_ci 92e1051a39Sopenharmony_ci prog = opt_init(argc, argv, pkcs8_options); 93e1051a39Sopenharmony_ci while ((o = opt_next()) != OPT_EOF) { 94e1051a39Sopenharmony_ci switch (o) { 95e1051a39Sopenharmony_ci case OPT_EOF: 96e1051a39Sopenharmony_ci case OPT_ERR: 97e1051a39Sopenharmony_ci opthelp: 98e1051a39Sopenharmony_ci BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 99e1051a39Sopenharmony_ci goto end; 100e1051a39Sopenharmony_ci case OPT_HELP: 101e1051a39Sopenharmony_ci opt_help(pkcs8_options); 102e1051a39Sopenharmony_ci ret = 0; 103e1051a39Sopenharmony_ci goto end; 104e1051a39Sopenharmony_ci case OPT_INFORM: 105e1051a39Sopenharmony_ci if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) 106e1051a39Sopenharmony_ci goto opthelp; 107e1051a39Sopenharmony_ci break; 108e1051a39Sopenharmony_ci case OPT_IN: 109e1051a39Sopenharmony_ci infile = opt_arg(); 110e1051a39Sopenharmony_ci break; 111e1051a39Sopenharmony_ci case OPT_OUTFORM: 112e1051a39Sopenharmony_ci if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) 113e1051a39Sopenharmony_ci goto opthelp; 114e1051a39Sopenharmony_ci break; 115e1051a39Sopenharmony_ci case OPT_OUT: 116e1051a39Sopenharmony_ci outfile = opt_arg(); 117e1051a39Sopenharmony_ci break; 118e1051a39Sopenharmony_ci case OPT_TOPK8: 119e1051a39Sopenharmony_ci topk8 = 1; 120e1051a39Sopenharmony_ci break; 121e1051a39Sopenharmony_ci case OPT_NOITER: 122e1051a39Sopenharmony_ci iter = 1; 123e1051a39Sopenharmony_ci break; 124e1051a39Sopenharmony_ci case OPT_NOCRYPT: 125e1051a39Sopenharmony_ci nocrypt = 1; 126e1051a39Sopenharmony_ci break; 127e1051a39Sopenharmony_ci case OPT_R_CASES: 128e1051a39Sopenharmony_ci if (!opt_rand(o)) 129e1051a39Sopenharmony_ci goto end; 130e1051a39Sopenharmony_ci break; 131e1051a39Sopenharmony_ci case OPT_PROV_CASES: 132e1051a39Sopenharmony_ci if (!opt_provider(o)) 133e1051a39Sopenharmony_ci goto end; 134e1051a39Sopenharmony_ci break; 135e1051a39Sopenharmony_ci case OPT_TRADITIONAL: 136e1051a39Sopenharmony_ci traditional = 1; 137e1051a39Sopenharmony_ci break; 138e1051a39Sopenharmony_ci case OPT_V2: 139e1051a39Sopenharmony_ci ciphername = opt_arg(); 140e1051a39Sopenharmony_ci break; 141e1051a39Sopenharmony_ci case OPT_V1: 142e1051a39Sopenharmony_ci pbe_nid = OBJ_txt2nid(opt_arg()); 143e1051a39Sopenharmony_ci if (pbe_nid == NID_undef) { 144e1051a39Sopenharmony_ci BIO_printf(bio_err, 145e1051a39Sopenharmony_ci "%s: Unknown PBE algorithm %s\n", prog, opt_arg()); 146e1051a39Sopenharmony_ci goto opthelp; 147e1051a39Sopenharmony_ci } 148e1051a39Sopenharmony_ci break; 149e1051a39Sopenharmony_ci case OPT_V2PRF: 150e1051a39Sopenharmony_ci pbe_nid = OBJ_txt2nid(opt_arg()); 151e1051a39Sopenharmony_ci if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) { 152e1051a39Sopenharmony_ci BIO_printf(bio_err, 153e1051a39Sopenharmony_ci "%s: Unknown PRF algorithm %s\n", prog, opt_arg()); 154e1051a39Sopenharmony_ci goto opthelp; 155e1051a39Sopenharmony_ci } 156e1051a39Sopenharmony_ci if (cipher == NULL) 157e1051a39Sopenharmony_ci cipher = (EVP_CIPHER *)EVP_aes_256_cbc(); 158e1051a39Sopenharmony_ci break; 159e1051a39Sopenharmony_ci case OPT_ITER: 160e1051a39Sopenharmony_ci iter = opt_int_arg(); 161e1051a39Sopenharmony_ci break; 162e1051a39Sopenharmony_ci case OPT_PASSIN: 163e1051a39Sopenharmony_ci passinarg = opt_arg(); 164e1051a39Sopenharmony_ci break; 165e1051a39Sopenharmony_ci case OPT_PASSOUT: 166e1051a39Sopenharmony_ci passoutarg = opt_arg(); 167e1051a39Sopenharmony_ci break; 168e1051a39Sopenharmony_ci case OPT_ENGINE: 169e1051a39Sopenharmony_ci e = setup_engine(opt_arg(), 0); 170e1051a39Sopenharmony_ci break; 171e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCRYPT 172e1051a39Sopenharmony_ci case OPT_SCRYPT: 173e1051a39Sopenharmony_ci scrypt_N = 16384; 174e1051a39Sopenharmony_ci scrypt_r = 8; 175e1051a39Sopenharmony_ci scrypt_p = 1; 176e1051a39Sopenharmony_ci if (cipher == NULL) 177e1051a39Sopenharmony_ci cipher = (EVP_CIPHER *)EVP_aes_256_cbc(); 178e1051a39Sopenharmony_ci break; 179e1051a39Sopenharmony_ci case OPT_SCRYPT_N: 180e1051a39Sopenharmony_ci if (!opt_long(opt_arg(), &scrypt_N) || scrypt_N <= 0) 181e1051a39Sopenharmony_ci goto opthelp; 182e1051a39Sopenharmony_ci break; 183e1051a39Sopenharmony_ci case OPT_SCRYPT_R: 184e1051a39Sopenharmony_ci if (!opt_long(opt_arg(), &scrypt_r) || scrypt_r <= 0) 185e1051a39Sopenharmony_ci goto opthelp; 186e1051a39Sopenharmony_ci break; 187e1051a39Sopenharmony_ci case OPT_SCRYPT_P: 188e1051a39Sopenharmony_ci if (!opt_long(opt_arg(), &scrypt_p) || scrypt_p <= 0) 189e1051a39Sopenharmony_ci goto opthelp; 190e1051a39Sopenharmony_ci break; 191e1051a39Sopenharmony_ci#endif 192e1051a39Sopenharmony_ci } 193e1051a39Sopenharmony_ci } 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci /* No extra arguments. */ 196e1051a39Sopenharmony_ci argc = opt_num_rest(); 197e1051a39Sopenharmony_ci if (argc != 0) 198e1051a39Sopenharmony_ci goto opthelp; 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_ci private = 1; 201e1051a39Sopenharmony_ci if (!app_RAND_load()) 202e1051a39Sopenharmony_ci goto end; 203e1051a39Sopenharmony_ci 204e1051a39Sopenharmony_ci if (ciphername != NULL) { 205e1051a39Sopenharmony_ci if (!opt_cipher(ciphername, &cipher)) 206e1051a39Sopenharmony_ci goto opthelp; 207e1051a39Sopenharmony_ci } 208e1051a39Sopenharmony_ci 209e1051a39Sopenharmony_ci if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { 210e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error getting passwords\n"); 211e1051a39Sopenharmony_ci goto end; 212e1051a39Sopenharmony_ci } 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci if ((pbe_nid == -1) && cipher == NULL) 215e1051a39Sopenharmony_ci cipher = (EVP_CIPHER *)EVP_aes_256_cbc(); 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci in = bio_open_default(infile, 'r', 218e1051a39Sopenharmony_ci informat == FORMAT_UNDEF ? FORMAT_PEM : informat); 219e1051a39Sopenharmony_ci if (in == NULL) 220e1051a39Sopenharmony_ci goto end; 221e1051a39Sopenharmony_ci out = bio_open_owner(outfile, outformat, private); 222e1051a39Sopenharmony_ci if (out == NULL) 223e1051a39Sopenharmony_ci goto end; 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci if (topk8) { 226e1051a39Sopenharmony_ci pkey = load_key(infile, informat, 1, passin, e, "key"); 227e1051a39Sopenharmony_ci if (pkey == NULL) 228e1051a39Sopenharmony_ci goto end; 229e1051a39Sopenharmony_ci if ((p8inf = EVP_PKEY2PKCS8(pkey)) == NULL) { 230e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error converting key\n"); 231e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 232e1051a39Sopenharmony_ci goto end; 233e1051a39Sopenharmony_ci } 234e1051a39Sopenharmony_ci if (nocrypt) { 235e1051a39Sopenharmony_ci assert(private); 236e1051a39Sopenharmony_ci if (outformat == FORMAT_PEM) { 237e1051a39Sopenharmony_ci PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); 238e1051a39Sopenharmony_ci } else if (outformat == FORMAT_ASN1) { 239e1051a39Sopenharmony_ci i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf); 240e1051a39Sopenharmony_ci } else { 241e1051a39Sopenharmony_ci BIO_printf(bio_err, "Bad format specified for key\n"); 242e1051a39Sopenharmony_ci goto end; 243e1051a39Sopenharmony_ci } 244e1051a39Sopenharmony_ci } else { 245e1051a39Sopenharmony_ci X509_ALGOR *pbe; 246e1051a39Sopenharmony_ci if (cipher) { 247e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_SCRYPT 248e1051a39Sopenharmony_ci if (scrypt_N && scrypt_r && scrypt_p) 249e1051a39Sopenharmony_ci pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, 0, NULL, 250e1051a39Sopenharmony_ci scrypt_N, scrypt_r, scrypt_p); 251e1051a39Sopenharmony_ci else 252e1051a39Sopenharmony_ci#endif 253e1051a39Sopenharmony_ci pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, 254e1051a39Sopenharmony_ci pbe_nid); 255e1051a39Sopenharmony_ci } else { 256e1051a39Sopenharmony_ci pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0); 257e1051a39Sopenharmony_ci } 258e1051a39Sopenharmony_ci if (pbe == NULL) { 259e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error setting PBE algorithm\n"); 260e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 261e1051a39Sopenharmony_ci goto end; 262e1051a39Sopenharmony_ci } 263e1051a39Sopenharmony_ci if (passout != NULL) { 264e1051a39Sopenharmony_ci p8pass = passout; 265e1051a39Sopenharmony_ci } else if (1) { 266e1051a39Sopenharmony_ci /* To avoid bit rot */ 267e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_UI_CONSOLE 268e1051a39Sopenharmony_ci p8pass = pass; 269e1051a39Sopenharmony_ci if (EVP_read_pw_string 270e1051a39Sopenharmony_ci (pass, sizeof(pass), "Enter Encryption Password:", 1)) { 271e1051a39Sopenharmony_ci X509_ALGOR_free(pbe); 272e1051a39Sopenharmony_ci goto end; 273e1051a39Sopenharmony_ci } 274e1051a39Sopenharmony_ci } else { 275e1051a39Sopenharmony_ci#endif 276e1051a39Sopenharmony_ci BIO_printf(bio_err, "Password required\n"); 277e1051a39Sopenharmony_ci goto end; 278e1051a39Sopenharmony_ci } 279e1051a39Sopenharmony_ci p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe); 280e1051a39Sopenharmony_ci if (p8 == NULL) { 281e1051a39Sopenharmony_ci X509_ALGOR_free(pbe); 282e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error encrypting key\n"); 283e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 284e1051a39Sopenharmony_ci goto end; 285e1051a39Sopenharmony_ci } 286e1051a39Sopenharmony_ci assert(private); 287e1051a39Sopenharmony_ci if (outformat == FORMAT_PEM) 288e1051a39Sopenharmony_ci PEM_write_bio_PKCS8(out, p8); 289e1051a39Sopenharmony_ci else if (outformat == FORMAT_ASN1) 290e1051a39Sopenharmony_ci i2d_PKCS8_bio(out, p8); 291e1051a39Sopenharmony_ci else { 292e1051a39Sopenharmony_ci BIO_printf(bio_err, "Bad format specified for key\n"); 293e1051a39Sopenharmony_ci goto end; 294e1051a39Sopenharmony_ci } 295e1051a39Sopenharmony_ci } 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_ci ret = 0; 298e1051a39Sopenharmony_ci goto end; 299e1051a39Sopenharmony_ci } 300e1051a39Sopenharmony_ci 301e1051a39Sopenharmony_ci if (nocrypt) { 302e1051a39Sopenharmony_ci if (informat == FORMAT_PEM || informat == FORMAT_UNDEF) { 303e1051a39Sopenharmony_ci p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL); 304e1051a39Sopenharmony_ci } else if (informat == FORMAT_ASN1) { 305e1051a39Sopenharmony_ci p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL); 306e1051a39Sopenharmony_ci } else { 307e1051a39Sopenharmony_ci BIO_printf(bio_err, "Bad format specified for key\n"); 308e1051a39Sopenharmony_ci goto end; 309e1051a39Sopenharmony_ci } 310e1051a39Sopenharmony_ci } else { 311e1051a39Sopenharmony_ci if (informat == FORMAT_PEM || informat == FORMAT_UNDEF) { 312e1051a39Sopenharmony_ci p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL); 313e1051a39Sopenharmony_ci } else if (informat == FORMAT_ASN1) { 314e1051a39Sopenharmony_ci p8 = d2i_PKCS8_bio(in, NULL); 315e1051a39Sopenharmony_ci } else { 316e1051a39Sopenharmony_ci BIO_printf(bio_err, "Bad format specified for key\n"); 317e1051a39Sopenharmony_ci goto end; 318e1051a39Sopenharmony_ci } 319e1051a39Sopenharmony_ci 320e1051a39Sopenharmony_ci if (p8 == NULL) { 321e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error reading key\n"); 322e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 323e1051a39Sopenharmony_ci goto end; 324e1051a39Sopenharmony_ci } 325e1051a39Sopenharmony_ci if (passin != NULL) { 326e1051a39Sopenharmony_ci p8pass = passin; 327e1051a39Sopenharmony_ci } else if (1) { 328e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_UI_CONSOLE 329e1051a39Sopenharmony_ci p8pass = pass; 330e1051a39Sopenharmony_ci if (EVP_read_pw_string(pass, sizeof(pass), "Enter Password:", 0)) { 331e1051a39Sopenharmony_ci BIO_printf(bio_err, "Can't read Password\n"); 332e1051a39Sopenharmony_ci goto end; 333e1051a39Sopenharmony_ci } 334e1051a39Sopenharmony_ci } else { 335e1051a39Sopenharmony_ci#endif 336e1051a39Sopenharmony_ci BIO_printf(bio_err, "Password required\n"); 337e1051a39Sopenharmony_ci goto end; 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); 340e1051a39Sopenharmony_ci } 341e1051a39Sopenharmony_ci 342e1051a39Sopenharmony_ci if (p8inf == NULL) { 343e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error decrypting key\n"); 344e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 345e1051a39Sopenharmony_ci goto end; 346e1051a39Sopenharmony_ci } 347e1051a39Sopenharmony_ci 348e1051a39Sopenharmony_ci if ((pkey = EVP_PKCS82PKEY(p8inf)) == NULL) { 349e1051a39Sopenharmony_ci BIO_printf(bio_err, "Error converting key\n"); 350e1051a39Sopenharmony_ci ERR_print_errors(bio_err); 351e1051a39Sopenharmony_ci goto end; 352e1051a39Sopenharmony_ci } 353e1051a39Sopenharmony_ci 354e1051a39Sopenharmony_ci assert(private); 355e1051a39Sopenharmony_ci if (outformat == FORMAT_PEM) { 356e1051a39Sopenharmony_ci if (traditional) 357e1051a39Sopenharmony_ci PEM_write_bio_PrivateKey_traditional(out, pkey, NULL, NULL, 0, 358e1051a39Sopenharmony_ci NULL, passout); 359e1051a39Sopenharmony_ci else 360e1051a39Sopenharmony_ci PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); 361e1051a39Sopenharmony_ci } else if (outformat == FORMAT_ASN1) { 362e1051a39Sopenharmony_ci i2d_PrivateKey_bio(out, pkey); 363e1051a39Sopenharmony_ci } else { 364e1051a39Sopenharmony_ci BIO_printf(bio_err, "Bad format specified for key\n"); 365e1051a39Sopenharmony_ci goto end; 366e1051a39Sopenharmony_ci } 367e1051a39Sopenharmony_ci ret = 0; 368e1051a39Sopenharmony_ci 369e1051a39Sopenharmony_ci end: 370e1051a39Sopenharmony_ci X509_SIG_free(p8); 371e1051a39Sopenharmony_ci PKCS8_PRIV_KEY_INFO_free(p8inf); 372e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 373e1051a39Sopenharmony_ci EVP_CIPHER_free(cipher); 374e1051a39Sopenharmony_ci release_engine(e); 375e1051a39Sopenharmony_ci BIO_free_all(out); 376e1051a39Sopenharmony_ci BIO_free(in); 377e1051a39Sopenharmony_ci OPENSSL_free(passin); 378e1051a39Sopenharmony_ci OPENSSL_free(passout); 379e1051a39Sopenharmony_ci 380e1051a39Sopenharmony_ci return ret; 381e1051a39Sopenharmony_ci} 382