]>
git.ipfire.org Git - thirdparty/openssl.git/blob - apps/storeutl.c
2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/opensslconf.h>
13 #include <openssl/err.h>
14 #include <openssl/pem.h>
15 #include <openssl/store.h>
17 static int process(const char *uri
, const UI_METHOD
*uimeth
, PW_CB_DATA
*uidata
,
18 int text
, int noout
, int recursive
, int indent
, BIO
*out
);
20 typedef enum OPTION_choice
{
21 OPT_ERR
= -1, OPT_EOF
= 0, OPT_HELP
, OPT_ENGINE
, OPT_OUT
, OPT_PASSIN
,
22 OPT_NOOUT
, OPT_TEXT
, OPT_RECURSIVE
25 const OPTIONS storeutl_options
[] = {
26 {OPT_HELP_STR
, 1, '-', "Usage: %s [options] uri\nValid options are:\n"},
27 {"help", OPT_HELP
, '-', "Display this summary"},
28 {"out", OPT_OUT
, '>', "Output file - default stdout"},
29 {"passin", OPT_PASSIN
, 's', "Input file pass phrase source"},
30 {"text", OPT_TEXT
, '-', "Print a text form of the objects"},
31 {"noout", OPT_NOOUT
, '-', "No PEM output, just status"},
32 #ifndef OPENSSL_NO_ENGINE
33 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
35 {"r", OPT_RECURSIVE
, '-', "Recurse through names"},
39 int storeutl_main(int argc
, char *argv
[])
41 int ret
= 1, noout
= 0, text
= 0, recursive
= 0;
42 char *outfile
= NULL
, *passin
= NULL
, *passinarg
= NULL
;
46 char *prog
= opt_init(argc
, argv
, storeutl_options
);
47 PW_CB_DATA pw_cb_data
;
49 while ((o
= opt_next()) != OPT_EOF
) {
54 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
57 opt_help(storeutl_options
);
64 passinarg
= opt_arg();
76 e
= setup_engine(opt_arg(), 0);
80 argc
= opt_num_rest();
84 BIO_printf(bio_err
, "%s: No URI given, nothing to do...\n", prog
);
88 BIO_printf(bio_err
, "%s: Unknown extra parameters after URI\n", prog
);
92 if (!app_passwd(passinarg
, NULL
, &passin
, NULL
)) {
93 BIO_printf(bio_err
, "Error getting passwords\n");
96 pw_cb_data
.password
= passin
;
97 pw_cb_data
.prompt_info
= argv
[0];
99 out
= bio_open_default(outfile
, 'w', FORMAT_TEXT
);
103 ret
= process(argv
[0], get_ui_method(), &pw_cb_data
, text
, noout
, recursive
,
108 OPENSSL_free(passin
);
113 static int indent_printf(int indent
, BIO
*bio
, const char *format
, ...)
118 va_start(args
, format
);
120 ret
= BIO_printf(bio
, "%*s", indent
, "") + BIO_vprintf(bio
, format
, args
);
126 static int process(const char *uri
, const UI_METHOD
*uimeth
, PW_CB_DATA
*uidata
,
127 int text
, int noout
, int recursive
, int indent
, BIO
*out
)
129 OSSL_STORE_CTX
*store_ctx
= NULL
;
130 int ret
= 1, items
= 0;
132 if ((store_ctx
= OSSL_STORE_open(uri
, uimeth
, uidata
, NULL
, NULL
))
134 BIO_printf(bio_err
, "Couldn't open file or uri %s\n", uri
);
135 ERR_print_errors(bio_err
);
139 /* From here on, we count errors, and we'll return the count at the end */
143 OSSL_STORE_INFO
*info
= OSSL_STORE_load(store_ctx
);
144 int type
= info
== NULL
? 0 : OSSL_STORE_INFO_get_type(info
);
145 const char *infostr
=
146 info
== NULL
? NULL
: OSSL_STORE_INFO_type_string(type
);
149 if (OSSL_STORE_eof(store_ctx
))
152 if (OSSL_STORE_error(store_ctx
)) {
156 ERR_print_errors(bio_err
);
162 "ERROR: OSSL_STORE_load() returned NULL without "
163 "eof or error indications\n");
164 BIO_printf(bio_err
, " This is an error in the loader\n");
165 ERR_print_errors(bio_err
);
170 if (type
== OSSL_STORE_INFO_NAME
) {
171 const char *name
= OSSL_STORE_INFO_get0_NAME(info
);
172 const char *desc
= OSSL_STORE_INFO_get0_NAME_description(info
);
173 indent_printf(indent
, bio_out
, "%d: %s: %s\n", items
, infostr
,
176 indent_printf(indent
, bio_out
, "%s\n", desc
);
178 indent_printf(indent
, bio_out
, "%d: %s\n", items
, infostr
);
182 * Unfortunately, PEM_X509_INFO_write_bio() is sorely lacking in
183 * functionality, so we must figure out how exactly to write things
187 case OSSL_STORE_INFO_NAME
:
189 const char *suburi
= OSSL_STORE_INFO_get0_NAME(info
);
190 ret
+= process(suburi
, uimeth
, uidata
, text
, noout
, recursive
,
194 case OSSL_STORE_INFO_PARAMS
:
196 EVP_PKEY_print_params(out
, OSSL_STORE_INFO_get0_PARAMS(info
),
199 PEM_write_bio_Parameters(out
,
200 OSSL_STORE_INFO_get0_PARAMS(info
));
202 case OSSL_STORE_INFO_PKEY
:
204 EVP_PKEY_print_private(out
, OSSL_STORE_INFO_get0_PKEY(info
),
207 PEM_write_bio_PrivateKey(out
, OSSL_STORE_INFO_get0_PKEY(info
),
208 NULL
, NULL
, 0, NULL
, NULL
);
210 case OSSL_STORE_INFO_CERT
:
212 X509_print(out
, OSSL_STORE_INFO_get0_CERT(info
));
214 PEM_write_bio_X509(out
, OSSL_STORE_INFO_get0_CERT(info
));
216 case OSSL_STORE_INFO_CRL
:
218 X509_CRL_print(out
, OSSL_STORE_INFO_get0_CRL(info
));
220 PEM_write_bio_X509_CRL(out
, OSSL_STORE_INFO_get0_CRL(info
));
223 BIO_printf(bio_err
, "!!! Unknown code\n");
228 OSSL_STORE_INFO_free(info
);
230 indent_printf(indent
, out
, "Total found: %d\n", items
);
232 if (!OSSL_STORE_close(store_ctx
)) {
233 ERR_print_errors(bio_err
);