=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/openssl/pkcs12.c,v retrieving revision 1.14 retrieving revision 1.15 diff -c -r1.14 -r1.15 *** src/usr.bin/openssl/pkcs12.c 2019/07/26 12:35:59 1.14 --- src/usr.bin/openssl/pkcs12.c 2021/10/23 14:48:33 1.15 *************** *** 1,4 **** ! /* $OpenBSD: pkcs12.c,v 1.14 2019/07/26 12:35:59 inoguchi Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ --- 1,4 ---- ! /* $OpenBSD: pkcs12.c,v 1.15 2021/10/23 14:48:33 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ *************** *** 84,93 **** int passlen, int options, char *pempass); int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); ! int print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); ! int alg_print(BIO *x, X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); static int set_pbe(BIO *err, int *ppbe, const char *str); --- 84,93 ---- int passlen, int options, char *pempass); int dump_certs_pkeys_bag(BIO *out, PKCS12_SAFEBAG *bags, char *pass, int passlen, int options, char *pempass); ! int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name); void hex_prin(BIO *out, unsigned char *buf, int len); ! int alg_print(BIO *x, const X509_ALGOR *alg); int cert_load(BIO *in, STACK_OF(X509) *sk); static int set_pbe(BIO *err, int *ppbe, const char *str); *************** *** 692,698 **** vret = get_cert_chain(ucert, store, &chain2); X509_STORE_free(store); ! if (!vret) { /* Exclude verified certificate */ for (i = 1; i < sk_X509_num(chain2); i++) sk_X509_push(certs, sk_X509_value( --- 692,698 ---- vret = get_cert_chain(ucert, store, &chain2); X509_STORE_free(store); ! if (vret == X509_V_OK) { /* Exclude verified certificate */ for (i = 1; i < sk_X509_num(chain2); i++) sk_X509_push(certs, sk_X509_value( *************** *** 701,707 **** X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { ! if (vret >= 0) BIO_printf(bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string( --- 701,707 ---- X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { ! if (vret != X509_V_ERR_UNSPECIFIED) BIO_printf(bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string( *************** *** 895,903 **** return 1; print_attribs(out, bag->attrib, "Bag Attributes"); p8 = bag->value.keybag; ! if (!(pkey = EVP_PKCS82PKEY(p8))) return 0; ! print_attribs(out, p8->attributes, "Key Attributes"); PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); --- 895,903 ---- return 1; print_attribs(out, bag->attrib, "Bag Attributes"); p8 = bag->value.keybag; ! if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) return 0; ! print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, NULL, pempass); EVP_PKEY_free(pkey); *************** *** 917,923 **** PKCS8_PRIV_KEY_INFO_free(p8); return 0; } ! print_attribs(out, p8->attributes, "Key Attributes"); PKCS8_PRIV_KEY_INFO_free(p8); PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, NULL, pempass); --- 917,923 ---- PKCS8_PRIV_KEY_INFO_free(p8); return 0; } ! print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes"); PKCS8_PRIV_KEY_INFO_free(p8); PEM_write_bio_PrivateKey(out, pkey, pkcs12_config.enc, NULL, 0, NULL, pempass); *************** *** 962,1004 **** } /* 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) { ! X509_STORE_CTX store_ctx; ! STACK_OF(X509) *chn; ! 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; ! return i; } int ! alg_print(BIO *x, X509_ALGOR *alg) { PBEPARAM *pbe; const unsigned char *p; --- 962,994 ---- } /* Given a single certificate return a verified chain or NULL if error */ int ! get_cert_chain(X509 *cert, X509_STORE *store, STACK_OF(X509) **out_chain) { ! X509_STORE_CTX *store_ctx = NULL; ! STACK_OF(X509) *chain = NULL; ! int ret = X509_V_ERR_UNSPECIFIED; ! if ((store_ctx = X509_STORE_CTX_new()) == NULL) goto err; ! if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) ! goto err; ! ! if (X509_verify_cert(store_ctx) > 0) { ! if ((chain = X509_STORE_CTX_get1_chain(store_ctx)) == NULL) ! goto err; ! } ! ret = X509_STORE_CTX_get_error(store_ctx); ! err: ! X509_STORE_CTX_free(store_ctx); ! *out_chain = chain; ! return ret; } int ! alg_print(BIO *x, const X509_ALGOR *alg) { PBEPARAM *pbe; const unsigned char *p; *************** *** 1031,1044 **** } /* Generalised attribute print: handle PKCS#8 and bag attributes */ int ! print_attribs(BIO *out, STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name) { X509_ATTRIBUTE *attr; ASN1_TYPE *av; ! char *value; ! int i, attr_nid; if (!attrlst) { BIO_printf(out, "%s: \n", name); return 1; --- 1021,1065 ---- } /* Generalised attribute print: handle PKCS#8 and bag attributes */ + void + print_attribute(BIO *out, const ASN1_TYPE *av) + { + char *value; + switch (av->type) { + case V_ASN1_BMPSTRING: + value = OPENSSL_uni2asc( + av->value.bmpstring->data, + av->value.bmpstring->length); + BIO_printf(out, "%s\n", value); + free(value); + break; + + case V_ASN1_OCTET_STRING: + hex_prin(out, av->value.octet_string->data, + av->value.octet_string->length); + BIO_printf(out, "\n"); + break; + + case V_ASN1_BIT_STRING: + hex_prin(out, av->value.bit_string->data, + av->value.bit_string->length); + BIO_printf(out, "\n"); + break; + + default: + BIO_printf(out, "\n", + av->type); + break; + } + } + int ! print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst, const char *name) { X509_ATTRIBUTE *attr; ASN1_TYPE *av; ! int i, j, attr_nid; if (!attrlst) { BIO_printf(out, "%s: \n", name); return 1; *************** *** 1049,1090 **** } BIO_printf(out, "%s\n", name); for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { attr = sk_X509_ATTRIBUTE_value(attrlst, i); ! attr_nid = OBJ_obj2nid(attr->object); BIO_printf(out, " "); if (attr_nid == NID_undef) { ! i2a_ASN1_OBJECT(out, attr->object); BIO_printf(out, ": "); } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); ! if (sk_ASN1_TYPE_num(attr->value.set)) { ! av = sk_ASN1_TYPE_value(attr->value.set, 0); ! switch (av->type) { ! case V_ASN1_BMPSTRING: ! value = OPENSSL_uni2asc( ! av->value.bmpstring->data, ! av->value.bmpstring->length); ! BIO_printf(out, "%s\n", value); ! free(value); ! break; ! ! case V_ASN1_OCTET_STRING: ! hex_prin(out, av->value.octet_string->data, ! av->value.octet_string->length); ! BIO_printf(out, "\n"); ! break; ! ! case V_ASN1_BIT_STRING: ! hex_prin(out, av->value.bit_string->data, ! av->value.bit_string->length); ! BIO_printf(out, "\n"); ! break; ! ! default: ! BIO_printf(out, "\n", ! av->type); ! break; } } else BIO_printf(out, "\n"); --- 1070,1091 ---- } BIO_printf(out, "%s\n", name); for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { + ASN1_OBJECT *obj; + attr = sk_X509_ATTRIBUTE_value(attrlst, i); ! obj = X509_ATTRIBUTE_get0_object(attr); ! attr_nid = OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)); BIO_printf(out, " "); if (attr_nid == NID_undef) { ! i2a_ASN1_OBJECT(out, obj); BIO_printf(out, ": "); } else BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid)); ! if (X509_ATTRIBUTE_count(attr)) { ! for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) { ! av = X509_ATTRIBUTE_get0_type(attr, j); ! print_attribute(out, av); } } else BIO_printf(out, "\n");