113d40330Schristos /*
2*b0d17251Schristos * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
313d40330Schristos *
4*b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
513d40330Schristos * this file except in compliance with the License. You can obtain a copy
613d40330Schristos * in the file LICENSE in the source distribution or at
713d40330Schristos * https://www.openssl.org/source/license.html
813d40330Schristos */
913d40330Schristos
1013d40330Schristos #include <openssl/opensslconf.h>
1113d40330Schristos
1213d40330Schristos #include "apps.h"
1313d40330Schristos #include "progs.h"
1413d40330Schristos #include <openssl/err.h>
1513d40330Schristos #include <openssl/pem.h>
1613d40330Schristos #include <openssl/store.h>
1713d40330Schristos #include <openssl/x509v3.h> /* s2i_ASN1_INTEGER */
1813d40330Schristos
1913d40330Schristos static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
2013d40330Schristos int expected, int criterion, OSSL_STORE_SEARCH *search,
2113d40330Schristos int text, int noout, int recursive, int indent, BIO *out,
22*b0d17251Schristos const char *prog, OSSL_LIB_CTX *libctx);
2313d40330Schristos
2413d40330Schristos typedef enum OPTION_choice {
25*b0d17251Schristos OPT_COMMON,
26*b0d17251Schristos OPT_ENGINE, OPT_OUT, OPT_PASSIN,
2713d40330Schristos OPT_NOOUT, OPT_TEXT, OPT_RECURSIVE,
2813d40330Schristos OPT_SEARCHFOR_CERTS, OPT_SEARCHFOR_KEYS, OPT_SEARCHFOR_CRLS,
2913d40330Schristos OPT_CRITERION_SUBJECT, OPT_CRITERION_ISSUER, OPT_CRITERION_SERIAL,
3013d40330Schristos OPT_CRITERION_FINGERPRINT, OPT_CRITERION_ALIAS,
31*b0d17251Schristos OPT_MD, OPT_PROV_ENUM
3213d40330Schristos } OPTION_CHOICE;
3313d40330Schristos
3413d40330Schristos const OPTIONS storeutl_options[] = {
35*b0d17251Schristos {OPT_HELP_STR, 1, '-', "Usage: %s [options] uri\n"},
36*b0d17251Schristos
37*b0d17251Schristos OPT_SECTION("General"),
3813d40330Schristos {"help", OPT_HELP, '-', "Display this summary"},
39*b0d17251Schristos {"", OPT_MD, '-', "Any supported digest"},
40*b0d17251Schristos #ifndef OPENSSL_NO_ENGINE
41*b0d17251Schristos {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
42*b0d17251Schristos #endif
43*b0d17251Schristos
44*b0d17251Schristos OPT_SECTION("Search"),
4513d40330Schristos {"certs", OPT_SEARCHFOR_CERTS, '-', "Search for certificates only"},
4613d40330Schristos {"keys", OPT_SEARCHFOR_KEYS, '-', "Search for keys only"},
4713d40330Schristos {"crls", OPT_SEARCHFOR_CRLS, '-', "Search for CRLs only"},
4813d40330Schristos {"subject", OPT_CRITERION_SUBJECT, 's', "Search by subject"},
4913d40330Schristos {"issuer", OPT_CRITERION_ISSUER, 's', "Search by issuer and serial, issuer name"},
5013d40330Schristos {"serial", OPT_CRITERION_SERIAL, 's', "Search by issuer and serial, serial number"},
5113d40330Schristos {"fingerprint", OPT_CRITERION_FINGERPRINT, 's', "Search by public key fingerprint, given in hex"},
5213d40330Schristos {"alias", OPT_CRITERION_ALIAS, 's', "Search by alias"},
5313d40330Schristos {"r", OPT_RECURSIVE, '-', "Recurse through names"},
54*b0d17251Schristos
55*b0d17251Schristos OPT_SECTION("Input"),
56*b0d17251Schristos {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
57*b0d17251Schristos
58*b0d17251Schristos OPT_SECTION("Output"),
59*b0d17251Schristos {"out", OPT_OUT, '>', "Output file - default stdout"},
60*b0d17251Schristos {"text", OPT_TEXT, '-', "Print a text form of the objects"},
61*b0d17251Schristos {"noout", OPT_NOOUT, '-', "No PEM output, just status"},
62*b0d17251Schristos
63*b0d17251Schristos OPT_PROV_OPTIONS,
64*b0d17251Schristos
65*b0d17251Schristos OPT_PARAMETERS(),
66*b0d17251Schristos {"uri", 0, 0, "URI of the store object"},
6713d40330Schristos {NULL}
6813d40330Schristos };
6913d40330Schristos
storeutl_main(int argc,char * argv[])7013d40330Schristos int storeutl_main(int argc, char *argv[])
7113d40330Schristos {
7213d40330Schristos int ret = 1, noout = 0, text = 0, recursive = 0;
7313d40330Schristos char *outfile = NULL, *passin = NULL, *passinarg = NULL;
7413d40330Schristos BIO *out = NULL;
7513d40330Schristos ENGINE *e = NULL;
7613d40330Schristos OPTION_CHOICE o;
7713d40330Schristos char *prog = opt_init(argc, argv, storeutl_options);
7813d40330Schristos PW_CB_DATA pw_cb_data;
7913d40330Schristos int expected = 0;
8013d40330Schristos int criterion = 0;
8113d40330Schristos X509_NAME *subject = NULL, *issuer = NULL;
8213d40330Schristos ASN1_INTEGER *serial = NULL;
8313d40330Schristos unsigned char *fingerprint = NULL;
8413d40330Schristos size_t fingerprintlen = 0;
85*b0d17251Schristos char *alias = NULL, *digestname = NULL;
8613d40330Schristos OSSL_STORE_SEARCH *search = NULL;
87*b0d17251Schristos EVP_MD *digest = NULL;
88*b0d17251Schristos OSSL_LIB_CTX *libctx = app_get0_libctx();
8913d40330Schristos
9013d40330Schristos while ((o = opt_next()) != OPT_EOF) {
9113d40330Schristos switch (o) {
9213d40330Schristos case OPT_EOF:
9313d40330Schristos case OPT_ERR:
9413d40330Schristos opthelp:
9513d40330Schristos BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
9613d40330Schristos goto end;
9713d40330Schristos case OPT_HELP:
9813d40330Schristos opt_help(storeutl_options);
9913d40330Schristos ret = 0;
10013d40330Schristos goto end;
10113d40330Schristos case OPT_OUT:
10213d40330Schristos outfile = opt_arg();
10313d40330Schristos break;
10413d40330Schristos case OPT_PASSIN:
10513d40330Schristos passinarg = opt_arg();
10613d40330Schristos break;
10713d40330Schristos case OPT_NOOUT:
10813d40330Schristos noout = 1;
10913d40330Schristos break;
11013d40330Schristos case OPT_TEXT:
11113d40330Schristos text = 1;
11213d40330Schristos break;
11313d40330Schristos case OPT_RECURSIVE:
11413d40330Schristos recursive = 1;
11513d40330Schristos break;
11613d40330Schristos case OPT_SEARCHFOR_CERTS:
11713d40330Schristos case OPT_SEARCHFOR_KEYS:
11813d40330Schristos case OPT_SEARCHFOR_CRLS:
11913d40330Schristos if (expected != 0) {
12013d40330Schristos BIO_printf(bio_err, "%s: only one search type can be given.\n",
12113d40330Schristos prog);
12213d40330Schristos goto end;
12313d40330Schristos }
12413d40330Schristos {
12513d40330Schristos static const struct {
12613d40330Schristos enum OPTION_choice choice;
12713d40330Schristos int type;
12813d40330Schristos } map[] = {
12913d40330Schristos {OPT_SEARCHFOR_CERTS, OSSL_STORE_INFO_CERT},
13013d40330Schristos {OPT_SEARCHFOR_KEYS, OSSL_STORE_INFO_PKEY},
13113d40330Schristos {OPT_SEARCHFOR_CRLS, OSSL_STORE_INFO_CRL},
13213d40330Schristos };
13313d40330Schristos size_t i;
13413d40330Schristos
13513d40330Schristos for (i = 0; i < OSSL_NELEM(map); i++) {
13613d40330Schristos if (o == map[i].choice) {
13713d40330Schristos expected = map[i].type;
13813d40330Schristos break;
13913d40330Schristos }
14013d40330Schristos }
14113d40330Schristos /*
14213d40330Schristos * If expected wasn't set at this point, it means the map
1434ce06407Schristos * isn't synchronised with the possible options leading here.
14413d40330Schristos */
14513d40330Schristos OPENSSL_assert(expected != 0);
14613d40330Schristos }
14713d40330Schristos break;
14813d40330Schristos case OPT_CRITERION_SUBJECT:
14913d40330Schristos if (criterion != 0) {
15013d40330Schristos BIO_printf(bio_err, "%s: criterion already given.\n",
15113d40330Schristos prog);
15213d40330Schristos goto end;
15313d40330Schristos }
15413d40330Schristos criterion = OSSL_STORE_SEARCH_BY_NAME;
15513d40330Schristos if (subject != NULL) {
15613d40330Schristos BIO_printf(bio_err, "%s: subject already given.\n",
15713d40330Schristos prog);
15813d40330Schristos goto end;
15913d40330Schristos }
160*b0d17251Schristos subject = parse_name(opt_arg(), MBSTRING_UTF8, 1, "subject");
161*b0d17251Schristos if (subject == NULL)
16213d40330Schristos goto end;
16313d40330Schristos break;
16413d40330Schristos case OPT_CRITERION_ISSUER:
16513d40330Schristos if (criterion != 0
166*b0d17251Schristos && criterion != OSSL_STORE_SEARCH_BY_ISSUER_SERIAL) {
16713d40330Schristos BIO_printf(bio_err, "%s: criterion already given.\n",
16813d40330Schristos prog);
16913d40330Schristos goto end;
17013d40330Schristos }
17113d40330Schristos criterion = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
17213d40330Schristos if (issuer != NULL) {
17313d40330Schristos BIO_printf(bio_err, "%s: issuer already given.\n",
17413d40330Schristos prog);
17513d40330Schristos goto end;
17613d40330Schristos }
177*b0d17251Schristos issuer = parse_name(opt_arg(), MBSTRING_UTF8, 1, "issuer");
178*b0d17251Schristos if (issuer == NULL)
17913d40330Schristos goto end;
18013d40330Schristos break;
18113d40330Schristos case OPT_CRITERION_SERIAL:
18213d40330Schristos if (criterion != 0
183*b0d17251Schristos && criterion != OSSL_STORE_SEARCH_BY_ISSUER_SERIAL) {
18413d40330Schristos BIO_printf(bio_err, "%s: criterion already given.\n",
18513d40330Schristos prog);
18613d40330Schristos goto end;
18713d40330Schristos }
18813d40330Schristos criterion = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
18913d40330Schristos if (serial != NULL) {
19013d40330Schristos BIO_printf(bio_err, "%s: serial number already given.\n",
19113d40330Schristos prog);
19213d40330Schristos goto end;
19313d40330Schristos }
19413d40330Schristos if ((serial = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) {
19513d40330Schristos BIO_printf(bio_err, "%s: can't parse serial number argument.\n",
19613d40330Schristos prog);
19713d40330Schristos goto end;
19813d40330Schristos }
19913d40330Schristos break;
20013d40330Schristos case OPT_CRITERION_FINGERPRINT:
20113d40330Schristos if (criterion != 0
20213d40330Schristos || (criterion == OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT
20313d40330Schristos && fingerprint != NULL)) {
20413d40330Schristos BIO_printf(bio_err, "%s: criterion already given.\n",
20513d40330Schristos prog);
20613d40330Schristos goto end;
20713d40330Schristos }
20813d40330Schristos criterion = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT;
20913d40330Schristos if (fingerprint != NULL) {
21013d40330Schristos BIO_printf(bio_err, "%s: fingerprint already given.\n",
21113d40330Schristos prog);
21213d40330Schristos goto end;
21313d40330Schristos }
21413d40330Schristos {
21513d40330Schristos long tmplen = 0;
21613d40330Schristos
21713d40330Schristos if ((fingerprint = OPENSSL_hexstr2buf(opt_arg(), &tmplen))
21813d40330Schristos == NULL) {
21913d40330Schristos BIO_printf(bio_err,
22013d40330Schristos "%s: can't parse fingerprint argument.\n",
22113d40330Schristos prog);
22213d40330Schristos goto end;
22313d40330Schristos }
22413d40330Schristos fingerprintlen = (size_t)tmplen;
22513d40330Schristos }
22613d40330Schristos break;
22713d40330Schristos case OPT_CRITERION_ALIAS:
22813d40330Schristos if (criterion != 0) {
22913d40330Schristos BIO_printf(bio_err, "%s: criterion already given.\n",
23013d40330Schristos prog);
23113d40330Schristos goto end;
23213d40330Schristos }
23313d40330Schristos criterion = OSSL_STORE_SEARCH_BY_ALIAS;
23413d40330Schristos if (alias != NULL) {
23513d40330Schristos BIO_printf(bio_err, "%s: alias already given.\n",
23613d40330Schristos prog);
23713d40330Schristos goto end;
23813d40330Schristos }
23913d40330Schristos if ((alias = OPENSSL_strdup(opt_arg())) == NULL) {
24013d40330Schristos BIO_printf(bio_err, "%s: can't parse alias argument.\n",
24113d40330Schristos prog);
24213d40330Schristos goto end;
24313d40330Schristos }
24413d40330Schristos break;
24513d40330Schristos case OPT_ENGINE:
24613d40330Schristos e = setup_engine(opt_arg(), 0);
24713d40330Schristos break;
24813d40330Schristos case OPT_MD:
249*b0d17251Schristos digestname = opt_unknown();
250*b0d17251Schristos break;
251*b0d17251Schristos case OPT_PROV_CASES:
252*b0d17251Schristos if (!opt_provider(o))
253*b0d17251Schristos goto end;
254*b0d17251Schristos break;
25513d40330Schristos }
25613d40330Schristos }
257*b0d17251Schristos
258*b0d17251Schristos /* One argument, the URI */
25913d40330Schristos argc = opt_num_rest();
26013d40330Schristos argv = opt_rest();
261*b0d17251Schristos if (argc != 1)
26213d40330Schristos goto opthelp;
263*b0d17251Schristos
264*b0d17251Schristos if (digestname != NULL) {
265*b0d17251Schristos if (!opt_md(digestname, &digest))
26613d40330Schristos goto opthelp;
26713d40330Schristos }
26813d40330Schristos
26913d40330Schristos if (criterion != 0) {
27013d40330Schristos switch (criterion) {
27113d40330Schristos case OSSL_STORE_SEARCH_BY_NAME:
27213d40330Schristos if ((search = OSSL_STORE_SEARCH_by_name(subject)) == NULL) {
27313d40330Schristos ERR_print_errors(bio_err);
27413d40330Schristos goto end;
27513d40330Schristos }
27613d40330Schristos break;
27713d40330Schristos case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL:
27813d40330Schristos if (issuer == NULL || serial == NULL) {
27913d40330Schristos BIO_printf(bio_err,
28013d40330Schristos "%s: both -issuer and -serial must be given.\n",
28113d40330Schristos prog);
28213d40330Schristos goto end;
28313d40330Schristos }
28413d40330Schristos if ((search = OSSL_STORE_SEARCH_by_issuer_serial(issuer, serial))
28513d40330Schristos == NULL) {
28613d40330Schristos ERR_print_errors(bio_err);
28713d40330Schristos goto end;
28813d40330Schristos }
28913d40330Schristos break;
29013d40330Schristos case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT:
29113d40330Schristos if ((search = OSSL_STORE_SEARCH_by_key_fingerprint(digest,
29213d40330Schristos fingerprint,
29313d40330Schristos fingerprintlen))
29413d40330Schristos == NULL) {
29513d40330Schristos ERR_print_errors(bio_err);
29613d40330Schristos goto end;
29713d40330Schristos }
29813d40330Schristos break;
29913d40330Schristos case OSSL_STORE_SEARCH_BY_ALIAS:
30013d40330Schristos if ((search = OSSL_STORE_SEARCH_by_alias(alias)) == NULL) {
30113d40330Schristos ERR_print_errors(bio_err);
30213d40330Schristos goto end;
30313d40330Schristos }
30413d40330Schristos break;
30513d40330Schristos }
30613d40330Schristos }
30713d40330Schristos
30813d40330Schristos if (!app_passwd(passinarg, NULL, &passin, NULL)) {
30913d40330Schristos BIO_printf(bio_err, "Error getting passwords\n");
31013d40330Schristos goto end;
31113d40330Schristos }
31213d40330Schristos pw_cb_data.password = passin;
31313d40330Schristos pw_cb_data.prompt_info = argv[0];
31413d40330Schristos
31513d40330Schristos out = bio_open_default(outfile, 'w', FORMAT_TEXT);
31613d40330Schristos if (out == NULL)
31713d40330Schristos goto end;
31813d40330Schristos
31913d40330Schristos ret = process(argv[0], get_ui_method(), &pw_cb_data,
32013d40330Schristos expected, criterion, search,
321*b0d17251Schristos text, noout, recursive, 0, out, prog, libctx);
32213d40330Schristos
32313d40330Schristos end:
324*b0d17251Schristos EVP_MD_free(digest);
32513d40330Schristos OPENSSL_free(fingerprint);
32613d40330Schristos OPENSSL_free(alias);
32713d40330Schristos ASN1_INTEGER_free(serial);
32813d40330Schristos X509_NAME_free(subject);
32913d40330Schristos X509_NAME_free(issuer);
33013d40330Schristos OSSL_STORE_SEARCH_free(search);
33113d40330Schristos BIO_free_all(out);
33213d40330Schristos OPENSSL_free(passin);
33313d40330Schristos release_engine(e);
33413d40330Schristos return ret;
33513d40330Schristos }
33613d40330Schristos
indent_printf(int indent,BIO * bio,const char * format,...)33713d40330Schristos static int indent_printf(int indent, BIO *bio, const char *format, ...)
33813d40330Schristos {
33913d40330Schristos va_list args;
34013d40330Schristos int ret;
34113d40330Schristos
34213d40330Schristos va_start(args, format);
34313d40330Schristos
34413d40330Schristos ret = BIO_printf(bio, "%*s", indent, "") + BIO_vprintf(bio, format, args);
34513d40330Schristos
34613d40330Schristos va_end(args);
34713d40330Schristos return ret;
34813d40330Schristos }
34913d40330Schristos
process(const char * uri,const UI_METHOD * uimeth,PW_CB_DATA * uidata,int expected,int criterion,OSSL_STORE_SEARCH * search,int text,int noout,int recursive,int indent,BIO * out,const char * prog,OSSL_LIB_CTX * libctx)35013d40330Schristos static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
35113d40330Schristos int expected, int criterion, OSSL_STORE_SEARCH *search,
35213d40330Schristos int text, int noout, int recursive, int indent, BIO *out,
353*b0d17251Schristos const char *prog, OSSL_LIB_CTX *libctx)
35413d40330Schristos {
35513d40330Schristos OSSL_STORE_CTX *store_ctx = NULL;
35613d40330Schristos int ret = 1, items = 0;
35713d40330Schristos
358*b0d17251Schristos if ((store_ctx = OSSL_STORE_open_ex(uri, libctx, app_get0_propq(), uimeth, uidata,
359*b0d17251Schristos NULL, NULL, NULL))
36013d40330Schristos == NULL) {
36113d40330Schristos BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri);
36213d40330Schristos ERR_print_errors(bio_err);
36313d40330Schristos return ret;
36413d40330Schristos }
36513d40330Schristos
36613d40330Schristos if (expected != 0) {
36713d40330Schristos if (!OSSL_STORE_expect(store_ctx, expected)) {
36813d40330Schristos ERR_print_errors(bio_err);
36913d40330Schristos goto end2;
37013d40330Schristos }
37113d40330Schristos }
37213d40330Schristos
37313d40330Schristos if (criterion != 0) {
37413d40330Schristos if (!OSSL_STORE_supports_search(store_ctx, criterion)) {
37513d40330Schristos BIO_printf(bio_err,
37613d40330Schristos "%s: the store scheme doesn't support the given search criteria.\n",
37713d40330Schristos prog);
37813d40330Schristos goto end2;
37913d40330Schristos }
38013d40330Schristos
38113d40330Schristos if (!OSSL_STORE_find(store_ctx, search)) {
38213d40330Schristos ERR_print_errors(bio_err);
38313d40330Schristos goto end2;
38413d40330Schristos }
38513d40330Schristos }
38613d40330Schristos
38713d40330Schristos /* From here on, we count errors, and we'll return the count at the end */
38813d40330Schristos ret = 0;
38913d40330Schristos
39013d40330Schristos for (;;) {
39113d40330Schristos OSSL_STORE_INFO *info = OSSL_STORE_load(store_ctx);
39213d40330Schristos int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info);
39313d40330Schristos const char *infostr =
39413d40330Schristos info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
39513d40330Schristos
39613d40330Schristos if (info == NULL) {
39713d40330Schristos if (OSSL_STORE_error(store_ctx)) {
39813d40330Schristos if (recursive)
39913d40330Schristos ERR_clear_error();
40013d40330Schristos else
40113d40330Schristos ERR_print_errors(bio_err);
402*b0d17251Schristos if (OSSL_STORE_eof(store_ctx))
403*b0d17251Schristos break;
40413d40330Schristos ret++;
40513d40330Schristos continue;
40613d40330Schristos }
40713d40330Schristos
408*b0d17251Schristos if (OSSL_STORE_eof(store_ctx))
409*b0d17251Schristos break;
410*b0d17251Schristos
41113d40330Schristos BIO_printf(bio_err,
41213d40330Schristos "ERROR: OSSL_STORE_load() returned NULL without "
41313d40330Schristos "eof or error indications\n");
41413d40330Schristos BIO_printf(bio_err, " This is an error in the loader\n");
41513d40330Schristos ERR_print_errors(bio_err);
41613d40330Schristos ret++;
41713d40330Schristos break;
41813d40330Schristos }
41913d40330Schristos
42013d40330Schristos if (type == OSSL_STORE_INFO_NAME) {
42113d40330Schristos const char *name = OSSL_STORE_INFO_get0_NAME(info);
42213d40330Schristos const char *desc = OSSL_STORE_INFO_get0_NAME_description(info);
42313d40330Schristos indent_printf(indent, bio_out, "%d: %s: %s\n", items, infostr,
42413d40330Schristos name);
42513d40330Schristos if (desc != NULL)
42613d40330Schristos indent_printf(indent, bio_out, "%s\n", desc);
42713d40330Schristos } else {
42813d40330Schristos indent_printf(indent, bio_out, "%d: %s\n", items, infostr);
42913d40330Schristos }
43013d40330Schristos
43113d40330Schristos /*
43213d40330Schristos * Unfortunately, PEM_X509_INFO_write_bio() is sorely lacking in
43313d40330Schristos * functionality, so we must figure out how exactly to write things
43413d40330Schristos * ourselves...
43513d40330Schristos */
43613d40330Schristos switch (type) {
43713d40330Schristos case OSSL_STORE_INFO_NAME:
43813d40330Schristos if (recursive) {
43913d40330Schristos const char *suburi = OSSL_STORE_INFO_get0_NAME(info);
44013d40330Schristos ret += process(suburi, uimeth, uidata,
44113d40330Schristos expected, criterion, search,
442*b0d17251Schristos text, noout, recursive, indent + 2, out, prog,
443*b0d17251Schristos libctx);
44413d40330Schristos }
44513d40330Schristos break;
44613d40330Schristos case OSSL_STORE_INFO_PARAMS:
44713d40330Schristos if (text)
44813d40330Schristos EVP_PKEY_print_params(out, OSSL_STORE_INFO_get0_PARAMS(info),
44913d40330Schristos 0, NULL);
45013d40330Schristos if (!noout)
45113d40330Schristos PEM_write_bio_Parameters(out,
45213d40330Schristos OSSL_STORE_INFO_get0_PARAMS(info));
45313d40330Schristos break;
454*b0d17251Schristos case OSSL_STORE_INFO_PUBKEY:
455*b0d17251Schristos if (text)
456*b0d17251Schristos EVP_PKEY_print_public(out, OSSL_STORE_INFO_get0_PUBKEY(info),
457*b0d17251Schristos 0, NULL);
458*b0d17251Schristos if (!noout)
459*b0d17251Schristos PEM_write_bio_PUBKEY(out, OSSL_STORE_INFO_get0_PUBKEY(info));
460*b0d17251Schristos break;
46113d40330Schristos case OSSL_STORE_INFO_PKEY:
46213d40330Schristos if (text)
46313d40330Schristos EVP_PKEY_print_private(out, OSSL_STORE_INFO_get0_PKEY(info),
46413d40330Schristos 0, NULL);
46513d40330Schristos if (!noout)
46613d40330Schristos PEM_write_bio_PrivateKey(out, OSSL_STORE_INFO_get0_PKEY(info),
46713d40330Schristos NULL, NULL, 0, NULL, NULL);
46813d40330Schristos break;
46913d40330Schristos case OSSL_STORE_INFO_CERT:
47013d40330Schristos if (text)
47113d40330Schristos X509_print(out, OSSL_STORE_INFO_get0_CERT(info));
47213d40330Schristos if (!noout)
47313d40330Schristos PEM_write_bio_X509(out, OSSL_STORE_INFO_get0_CERT(info));
47413d40330Schristos break;
47513d40330Schristos case OSSL_STORE_INFO_CRL:
47613d40330Schristos if (text)
47713d40330Schristos X509_CRL_print(out, OSSL_STORE_INFO_get0_CRL(info));
47813d40330Schristos if (!noout)
47913d40330Schristos PEM_write_bio_X509_CRL(out, OSSL_STORE_INFO_get0_CRL(info));
48013d40330Schristos break;
48113d40330Schristos default:
48213d40330Schristos BIO_printf(bio_err, "!!! Unknown code\n");
48313d40330Schristos ret++;
48413d40330Schristos break;
48513d40330Schristos }
48613d40330Schristos items++;
48713d40330Schristos OSSL_STORE_INFO_free(info);
48813d40330Schristos }
48913d40330Schristos indent_printf(indent, out, "Total found: %d\n", items);
49013d40330Schristos
49113d40330Schristos end2:
49213d40330Schristos if (!OSSL_STORE_close(store_ctx)) {
49313d40330Schristos ERR_print_errors(bio_err);
49413d40330Schristos ret++;
49513d40330Schristos }
49613d40330Schristos
49713d40330Schristos return ret;
49813d40330Schristos }
499