X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=apps%2Fpkcs12.c;h=f8806b9a6af149cb0f68fd01d0b910db5a975b7f;hb=a66234bc86a959e628e2010687c6fdf0fdbfdac3;hp=0a4ee3ed1033ddecee19b3d995d5847162366803;hpb=25aaa98aa249d26391c1994d2de449562c8b8b99;p=openssl.git diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 0a4ee3ed10..f8806b9a6a 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -1,63 +1,16 @@ /* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include -#if !defined(OPENSSL_NO_DES) +#if defined(OPENSSL_NO_DES) +NON_EMPTY_TRANSLATION_UNIT +#else # include # include @@ -74,19 +27,21 @@ # define CLCERTS 0x8 # define CACERTS 0x10 -int get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain); -int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int passlen, - int options, char *pempass, const EVP_CIPHER *enc); -int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, - char *pass, int passlen, int options, char *pempass, - const EVP_CIPHER *enc); -int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, - int passlen, int options, char *pempass, - const EVP_CIPHER *enc); -int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, +static int get_cert_chain(X509 *cert, X509_STORE *store, + STACK_OF(X509) **chain); +int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, + const char *pass, int passlen, int options, + char *pempass, const EVP_CIPHER *enc); +int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, + const char *pass, int passlen, int options, + char *pempass, const EVP_CIPHER *enc); +int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bags, + const char *pass, int passlen, + int options, char *pempass, const EVP_CIPHER *enc); +int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); -static int alg_print(X509_ALGOR *alg); +static int alg_print(const X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); static int set_pbe(int *ppbe, const char *str); @@ -98,7 +53,7 @@ typedef enum OPTION_choice { OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME, OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, - OPT_CAFILE, OPT_ENGINE + OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE } OPTION_CHOICE; OPTIONS pkcs12_options[] = { @@ -149,10 +104,14 @@ OPTIONS pkcs12_options[] = { {"password", OPT_PASSWORD, 's', "Set import/export password source"}, {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, + {"no-CAfile", OPT_NOCAFILE, '-', + "Do not load the default certificates file"}, + {"no-CApath", OPT_NOCAPATH, '-', + "Do not load certificates from the default certificates directory"}, + {"", OPT_CIPHER, '-', "Any supported cipher"}, # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, # endif - {"", OPT_CIPHER, '-', "Any supported cipher"}, {NULL} }; @@ -160,7 +119,7 @@ int pkcs12_main(int argc, char **argv) { char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL; char *name = NULL, *csp_name = NULL; - char pass[50], macpass[50]; + char pass[2048] = "", macpass[2048] = ""; int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; # ifndef OPENSSL_NO_RC2 @@ -169,11 +128,13 @@ int pkcs12_main(int argc, char **argv) int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; # endif int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - int ret = 1, macver = 1, noprompt = 0, add_lmk = 0; + int ret = 1, macver = 1, add_lmk = 0, private = 0; + int noprompt = 0; char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL; - char *cpass = NULL, *mpass = NULL, *CApath = NULL, *CAfile = NULL; - char *prog; + char *cpass = NULL, *mpass = NULL; + const char *CApath = NULL, *CAfile = NULL, *prog; + int noCApath = 0, noCAfile = 0; ENGINE *e = NULL; BIO *in = NULL, *out = NULL; PKCS12 *p12 = NULL; @@ -307,13 +268,22 @@ int pkcs12_main(int argc, char **argv) case OPT_CAFILE: CAfile = opt_arg(); break; + case OPT_NOCAPATH: + noCApath = 1; + break; + case OPT_NOCAFILE: + noCAfile = 1; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; } } argc = opt_num_rest(); - argv = opt_rest(); + if (argc != 0) + goto opthelp; + + private = 1; if (passarg) { if (export_cert) @@ -349,18 +319,17 @@ int pkcs12_main(int argc, char **argv) app_RAND_load_files(inrand)); } - in = bio_open_default(infile, "rb"); - if (in == NULL) - goto end; - - out = bio_open_default(outfile, "wb"); - if (out == NULL) - goto end; - if (twopass) { - if (EVP_read_pw_string - (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { - BIO_printf(bio_err, "Can't read Password\n"); + if (1) { +#ifndef OPENSSL_NO_UI + if (EVP_read_pw_string + (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) { + BIO_printf(bio_err, "Can't read Password\n"); + goto end; + } + } else { +#endif + BIO_printf(bio_err, "Unsupported option -twopass\n"); goto end; } } @@ -390,9 +359,8 @@ int pkcs12_main(int argc, char **argv) /* Load in all certs in input file */ if (!(options & NOCERTS)) { - certs = load_certs(infile, FORMAT_PEM, NULL, e, - "certificates"); - if (!certs) + if (!load_certs(infile, &certs, FORMAT_PEM, NULL, + "certificates")) goto export_end; if (key) { @@ -420,13 +388,9 @@ int pkcs12_main(int argc, char **argv) /* Add any more certificates asked for */ if (certfile) { - STACK_OF(X509) *morecerts = NULL; - if (!(morecerts = load_certs(certfile, FORMAT_PEM, NULL, e, - "certificates from certfile"))) + if (!load_certs(certfile, &certs, FORMAT_PEM, NULL, + "certificates from certfile")) goto export_end; - while (sk_X509_num(morecerts) > 0) - sk_X509_push(certs, sk_X509_shift(morecerts)); - sk_X509_free(morecerts); } /* If chaining get chain from user cert */ @@ -434,13 +398,14 @@ int pkcs12_main(int argc, char **argv) int vret; STACK_OF(X509) *chain2; X509_STORE *store; - if (!(store = setup_verify(CAfile, CApath))) + if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) + == NULL) goto export_end; vret = get_cert_chain(ucert, store, &chain2); X509_STORE_free(store); - if (!vret) { + if (vret == X509_V_OK) { /* Exclude verified certificate */ for (i = 1; i < sk_X509_num(chain2); i++) sk_X509_push(certs, sk_X509_value(chain2, i)); @@ -448,7 +413,7 @@ int pkcs12_main(int argc, char **argv) X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { - if (vret >= 0) + if (vret != X509_V_ERR_UNSPECIFIED) BIO_printf(bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string(vret)); else @@ -472,14 +437,23 @@ int pkcs12_main(int argc, char **argv) if (add_lmk && key) EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1); - if (!noprompt && - EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", - 1)) { - BIO_printf(bio_err, "Can't read Password\n"); - goto export_end; + if (!noprompt) { + if (1) { +#ifndef OPENSSL_NO_UI + if (EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:", + 1)) { + BIO_printf(bio_err, "Can't read Password\n"); + goto export_end; + } + } else { +#endif + BIO_printf(bio_err, "Password required\n"); + goto export_end; + } } + if (!twopass) - BUF_strlcpy(macpass, pass, sizeof macpass); + OPENSSL_strlcpy(macpass, pass, sizeof macpass); p12 = PKCS12_create(cpass, name, key, ucert, certs, key_pbe, cert_pbe, iter, -1, keytype); @@ -497,6 +471,12 @@ int pkcs12_main(int argc, char **argv) if (maciter != -1) PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); + assert(private); + + out = bio_open_owner(outfile, FORMAT_PKCS12, private); + if (out == NULL) + goto end; + i2d_PKCS12_bio(out, p12); ret = 0; @@ -511,24 +491,47 @@ int pkcs12_main(int argc, char **argv) } - if (!(p12 = d2i_PKCS12_bio(in, NULL))) { + in = bio_open_default(infile, 'r', FORMAT_PKCS12); + if (in == NULL) + goto end; + out = bio_open_owner(outfile, FORMAT_PEM, private); + if (out == NULL) + goto end; + + if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) { ERR_print_errors(bio_err); goto end; } - if (!noprompt - && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", - 0)) { - BIO_printf(bio_err, "Can't read Password\n"); - goto end; + if (!noprompt) { + if (1) { +#ifndef OPENSSL_NO_UI + if (EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:", + 0)) { + BIO_printf(bio_err, "Can't read Password\n"); + goto end; + } + } else { +#endif + BIO_printf(bio_err, "Password required\n"); + goto end; + } } if (!twopass) - BUF_strlcpy(macpass, pass, sizeof macpass); - - if ((options & INFO) && p12->mac) - BIO_printf(bio_err, "MAC Iteration %ld\n", - p12->mac->iter ? ASN1_INTEGER_get(p12->mac->iter) : 1); + OPENSSL_strlcpy(macpass, pass, sizeof macpass); + + if ((options & INFO) && PKCS12_mac_present(p12)) { + const ASN1_INTEGER *tmaciter; + const X509_ALGOR *macalgid; + const ASN1_OBJECT *macobj; + PKCS12_get0_mac(NULL, &macalgid, NULL, &tmaciter, p12); + X509_ALGOR_get0(&macobj, NULL, NULL, macalgid); + BIO_puts(bio_err, "MAC:"); + i2a_ASN1_OBJECT(bio_err, macobj); + BIO_printf(bio_err, " Iteration %ld\n", + tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L); + } if (macver) { /* If we enter empty password try no password first */ if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { @@ -542,6 +545,7 @@ int pkcs12_main(int argc, char **argv) } } + assert(private); if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors(bio_err); @@ -560,7 +564,7 @@ int pkcs12_main(int argc, char **argv) return (ret); } -int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, +int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, int passlen, int options, char *pempass, const EVP_CIPHER *enc) { @@ -570,7 +574,7 @@ int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, int ret = 0; PKCS7 *p7; - if (!(asafes = PKCS12_unpack_authsafes(p12))) + if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) return 0; for (i = 0; i < sk_PKCS7_num(asafes); i++) { p7 = sk_PKCS7_value(asafes, i); @@ -604,9 +608,9 @@ int dump_certs_keys_p12(BIO *out, PKCS12 *p12, char *pass, return ret; } -int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, - char *pass, int passlen, int options, char *pempass, - const EVP_CIPHER *enc) +int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags, + const char *pass, int passlen, int options, + char *pempass, const EVP_CIPHER *enc) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { @@ -618,46 +622,56 @@ int dump_certs_pkeys_bags(BIO *out, STACK_OF(PKCS12_SAFEBAG) *bags, return 1; } -int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, - int passlen, int options, char *pempass, - const EVP_CIPHER *enc) +int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag, + const char *pass, int passlen, int options, + char *pempass, const EVP_CIPHER *enc) { EVP_PKEY *pkey; PKCS8_PRIV_KEY_INFO *p8; + const PKCS8_PRIV_KEY_INFO *p8c; X509 *x509; + const STACK_OF(X509_ATTRIBUTE) *attrs; + int ret = 0; + + attrs = PKCS12_SAFEBAG_get0_attrs(bag); - switch (M_PKCS12_bag_type(bag)) { + switch (PKCS12_SAFEBAG_get_nid(bag)) { case NID_keyBag: if (options & INFO) BIO_printf(bio_err, "Key bag\n"); if (options & NOKEYS) return 1; - print_attribs(out, bag->attrib, "Bag Attributes"); - p8 = bag->value.keybag; - if (!(pkey = EVP_PKCS82PKEY(p8))) + print_attribs(out, attrs, "Bag Attributes"); + p8c = PKCS12_SAFEBAG_get0_p8inf(bag); + if ((pkey = EVP_PKCS82PKEY(p8c)) == NULL) return 0; - print_attribs(out, p8->attributes, "Key Attributes"); - PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + print_attribs(out, PKCS8_pkey_get0_attrs(p8c), "Key Attributes"); + ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break; case NID_pkcs8ShroudedKeyBag: if (options & INFO) { + const X509_SIG *tp8; + const X509_ALGOR *tp8alg; + BIO_printf(bio_err, "Shrouded Keybag: "); - alg_print(bag->value.shkeybag->algor); + tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag); + X509_SIG_get0(tp8, &tp8alg, NULL); + alg_print(tp8alg); } if (options & NOKEYS) return 1; - print_attribs(out, bag->attrib, "Bag Attributes"); - if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) + print_attribs(out, attrs, "Bag Attributes"); + if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL) return 0; - if (!(pkey = EVP_PKCS82PKEY(p8))) { + if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) { PKCS8_PRIV_KEY_INFO_free(p8); return 0; } - print_attribs(out, p8->attributes, "Key Attributes"); + print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); PKCS8_PRIV_KEY_INFO_free(p8); - PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); + ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); break; @@ -666,84 +680,134 @@ int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bag, char *pass, BIO_printf(bio_err, "Certificate bag\n"); if (options & NOCERTS) return 1; - if (PKCS12_get_attr(bag, NID_localKeyID)) { + if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)) { if (options & CACERTS) return 1; } else if (options & CLCERTS) return 1; - print_attribs(out, bag->attrib, "Bag Attributes"); - if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + print_attribs(out, attrs, "Bag Attributes"); + if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) return 1; - if (!(x509 = PKCS12_certbag2x509(bag))) + if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL) return 0; dump_cert_text(out, x509); - PEM_write_bio_X509(out, x509); + ret = PEM_write_bio_X509(out, x509); X509_free(x509); break; case NID_safeContentsBag: if (options & INFO) BIO_printf(bio_err, "Safe Contents bag\n"); - print_attribs(out, bag->attrib, "Bag Attributes"); - return dump_certs_pkeys_bags(out, bag->value.safes, pass, - passlen, options, pempass, enc); + print_attribs(out, attrs, "Bag Attributes"); + return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag), + pass, passlen, options, pempass, enc); default: BIO_printf(bio_err, "Warning unsupported bag type: "); - i2a_ASN1_OBJECT(bio_err, bag->type); + i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag)); BIO_printf(bio_err, "\n"); return 1; } - return 1; + return ret; } /* Given a single certificate return a verified chain or NULL if error */ -/* Hope this is OK .... */ - -int get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **chain) +static int get_cert_chain(X509 *cert, X509_STORE *store, + STACK_OF(X509) **chain) { - X509_STORE_CTX store_ctx; - STACK_OF(X509) *chn; + X509_STORE_CTX *store_ctx = NULL; + STACK_OF(X509) *chn = NULL; int i = 0; - /* - * FIXME: Should really check the return status of X509_STORE_CTX_init - * for an error, but how that fits into the return value of this function - * is less obvious. - */ - X509_STORE_CTX_init(&store_ctx, store, cert, NULL); - if (X509_verify_cert(&store_ctx) <= 0) { - i = X509_STORE_CTX_get_error(&store_ctx); - if (i == 0) - /* - * avoid returning 0 if X509_verify_cert() did not set an - * appropriate error value in the context - */ - i = -1; - chn = NULL; - goto err; - } else - chn = X509_STORE_CTX_get1_chain(&store_ctx); - err: - X509_STORE_CTX_cleanup(&store_ctx); - *chain = chn; + store_ctx = X509_STORE_CTX_new(); + if (store_ctx == NULL) { + i = X509_V_ERR_UNSPECIFIED; + goto end; + } + if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) { + i = X509_V_ERR_UNSPECIFIED; + goto end; + } + + if (X509_verify_cert(store_ctx) > 0) + chn = X509_STORE_CTX_get1_chain(store_ctx); + else if ((i = X509_STORE_CTX_get_error(store_ctx)) == 0) + i = X509_V_ERR_UNSPECIFIED; + +end: + X509_STORE_CTX_free(store_ctx); + *chain = chn; return i; } -static int alg_print(X509_ALGOR *alg) +static int alg_print(const X509_ALGOR *alg) { - PBEPARAM *pbe; - const unsigned char *p = alg->parameter->value.sequence->data; + int pbenid, aparamtype; + const ASN1_OBJECT *aoid; + const void *aparam; + PBEPARAM *pbe = NULL; - pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); - if (!pbe) - return 1; - BIO_printf(bio_err, "%s, Iteration %ld\n", - OBJ_nid2ln(OBJ_obj2nid(alg->algorithm)), - ASN1_INTEGER_get(pbe->iter)); - PBEPARAM_free(pbe); + X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg); + + pbenid = OBJ_obj2nid(aoid); + + BIO_printf(bio_err, "%s", OBJ_nid2ln(pbenid)); + + /* + * If PBE algorithm is PBES2 decode algorithm parameters + * for additional details. + */ + if (pbenid == NID_pbes2) { + PBE2PARAM *pbe2 = NULL; + int encnid; + if (aparamtype == V_ASN1_SEQUENCE) + pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM)); + if (pbe2 == NULL) { + BIO_puts(bio_err, ""); + goto done; + } + X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc); + pbenid = OBJ_obj2nid(aoid); + X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption); + encnid = OBJ_obj2nid(aoid); + BIO_printf(bio_err, ", %s, %s", OBJ_nid2ln(pbenid), + OBJ_nid2sn(encnid)); + /* If KDF is PBKDF2 decode parameters */ + if (pbenid == NID_id_pbkdf2) { + PBKDF2PARAM *kdf = NULL; + int prfnid; + if (aparamtype == V_ASN1_SEQUENCE) + kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM)); + if (kdf == NULL) { + BIO_puts(bio_err, ""); + goto done; + } + + if (kdf->prf == NULL) { + prfnid = NID_hmacWithSHA1; + } else { + X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf); + prfnid = OBJ_obj2nid(aoid); + } + BIO_printf(bio_err, ", Iteration %ld, PRF %s", + ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid)); + PBKDF2PARAM_free(kdf); + } + PBE2PARAM_free(pbe2); + } else { + if (aparamtype == V_ASN1_SEQUENCE) + pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM)); + if (pbe == NULL) { + BIO_puts(bio_err, ""); + goto done; + } + BIO_printf(bio_err, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter)); + PBEPARAM_free(pbe); + } + done: + BIO_puts(bio_err, "\n"); return 1; } @@ -765,7 +829,7 @@ int cert_load(BIO *in, STACK_OF(X509) *sk) /* Generalised attribute print: handle PKCS#8 and bag attributes */ -int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, +int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name) { X509_ATTRIBUTE *attr; @@ -836,7 +900,7 @@ static int set_pbe(int *ppbe, const char *str) { if (!str) return 0; - if (!strcmp(str, "NONE")) { + if (strcmp(str, "NONE") == 0) { *ppbe = -1; return 1; }