]>
git.ipfire.org Git - thirdparty/openssl.git/blob - apps/storeutl.c
2 * Copyright 2016-2018 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>
14 #include <openssl/err.h>
15 #include <openssl/pem.h>
16 #include <openssl/store.h>
18 static int process(const char *uri
, const UI_METHOD
*uimeth
, PW_CB_DATA
*uidata
,
19 int text
, int noout
, int recursive
, int indent
, BIO
*out
);
21 typedef enum OPTION_choice
{
22 OPT_ERR
= -1, OPT_EOF
= 0, OPT_HELP
, OPT_ENGINE
, OPT_OUT
, OPT_PASSIN
,
23 OPT_NOOUT
, OPT_TEXT
, OPT_RECURSIVE
26 const OPTIONS storeutl_options
[] = {
27 {OPT_HELP_STR
, 1, '-', "Usage: %s [options] uri\nValid options are:\n"},
28 {"help", OPT_HELP
, '-', "Display this summary"},
29 {"out", OPT_OUT
, '>', "Output file - default stdout"},
30 {"passin", OPT_PASSIN
, 's', "Input file pass phrase source"},
31 {"text", OPT_TEXT
, '-', "Print a text form of the objects"},
32 {"noout", OPT_NOOUT
, '-', "No PEM output, just status"},
33 #ifndef OPENSSL_NO_ENGINE
34 {"engine", OPT_ENGINE
, 's', "Use engine, possibly a hardware device"},
36 {"r", OPT_RECURSIVE
, '-', "Recurse through names"},
40 int storeutl_main(int argc
, char *argv
[])
42 int ret
= 1, noout
= 0, text
= 0, recursive
= 0;
43 char *outfile
= NULL
, *passin
= NULL
, *passinarg
= NULL
;
47 char *prog
= opt_init(argc
, argv
, storeutl_options
);
48 PW_CB_DATA pw_cb_data
;
50 while ((o
= opt_next()) != OPT_EOF
) {
55 BIO_printf(bio_err
, "%s: Use -help for summary.\n", prog
);
58 opt_help(storeutl_options
);
65 passinarg
= opt_arg();
77 e
= setup_engine(opt_arg(), 0);
81 argc
= opt_num_rest();
85 BIO_printf(bio_err
, "%s: No URI given, nothing to do...\n", prog
);
89 BIO_printf(bio_err
, "%s: Unknown extra parameters after URI\n", prog
);
93 if (!app_passwd(passinarg
, NULL
, &passin
, NULL
)) {
94 BIO_printf(bio_err
, "Error getting passwords\n");
97 pw_cb_data
.password
= passin
;
98 pw_cb_data
.prompt_info
= argv
[0];
100 out
= bio_open_default(outfile
, 'w', FORMAT_TEXT
);
104 ret
= process(argv
[0], get_ui_method(), &pw_cb_data
, text
, noout
, recursive
,
109 OPENSSL_free(passin
);
114 static int indent_printf(int indent
, BIO
*bio
, const char *format
, ...)
119 va_start(args
, format
);
121 ret
= BIO_printf(bio
, "%*s", indent
, "") + BIO_vprintf(bio
, format
, args
);
127 static int process(const char *uri
, const UI_METHOD
*uimeth
, PW_CB_DATA
*uidata
,
128 int text
, int noout
, int recursive
, int indent
, BIO
*out
)
130 OSSL_STORE_CTX
*store_ctx
= NULL
;
131 int ret
= 1, items
= 0;
133 if ((store_ctx
= OSSL_STORE_open(uri
, uimeth
, uidata
, NULL
, NULL
))
135 BIO_printf(bio_err
, "Couldn't open file or uri %s\n", uri
);
136 ERR_print_errors(bio_err
);
140 /* From here on, we count errors, and we'll return the count at the end */
144 OSSL_STORE_INFO
*info
= OSSL_STORE_load(store_ctx
);
145 int type
= info
== NULL
? 0 : OSSL_STORE_INFO_get_type(info
);
146 const char *infostr
=
147 info
== NULL
? NULL
: OSSL_STORE_INFO_type_string(type
);
150 if (OSSL_STORE_eof(store_ctx
))
153 if (OSSL_STORE_error(store_ctx
)) {
157 ERR_print_errors(bio_err
);
163 "ERROR: OSSL_STORE_load() returned NULL without "
164 "eof or error indications\n");
165 BIO_printf(bio_err
, " This is an error in the loader\n");
166 ERR_print_errors(bio_err
);
171 if (type
== OSSL_STORE_INFO_NAME
) {
172 const char *name
= OSSL_STORE_INFO_get0_NAME(info
);
173 const char *desc
= OSSL_STORE_INFO_get0_NAME_description(info
);
174 indent_printf(indent
, bio_out
, "%d: %s: %s\n", items
, infostr
,
177 indent_printf(indent
, bio_out
, "%s\n", desc
);
179 indent_printf(indent
, bio_out
, "%d: %s\n", items
, infostr
);
183 * Unfortunately, PEM_X509_INFO_write_bio() is sorely lacking in
184 * functionality, so we must figure out how exactly to write things
188 case OSSL_STORE_INFO_NAME
:
190 const char *suburi
= OSSL_STORE_INFO_get0_NAME(info
);
191 ret
+= process(suburi
, uimeth
, uidata
, text
, noout
, recursive
,
195 case OSSL_STORE_INFO_PARAMS
:
197 EVP_PKEY_print_params(out
, OSSL_STORE_INFO_get0_PARAMS(info
),
200 PEM_write_bio_Parameters(out
,
201 OSSL_STORE_INFO_get0_PARAMS(info
));
203 case OSSL_STORE_INFO_PKEY
:
205 EVP_PKEY_print_private(out
, OSSL_STORE_INFO_get0_PKEY(info
),
208 PEM_write_bio_PrivateKey(out
, OSSL_STORE_INFO_get0_PKEY(info
),
209 NULL
, NULL
, 0, NULL
, NULL
);
211 case OSSL_STORE_INFO_CERT
:
213 X509_print(out
, OSSL_STORE_INFO_get0_CERT(info
));
215 PEM_write_bio_X509(out
, OSSL_STORE_INFO_get0_CERT(info
));
217 case OSSL_STORE_INFO_CRL
:
219 X509_CRL_print(out
, OSSL_STORE_INFO_get0_CRL(info
));
221 PEM_write_bio_X509_CRL(out
, OSSL_STORE_INFO_get0_CRL(info
));
224 BIO_printf(bio_err
, "!!! Unknown code\n");
229 OSSL_STORE_INFO_free(info
);
231 indent_printf(indent
, out
, "Total found: %d\n", items
);
233 if (!OSSL_STORE_close(store_ctx
)) {
234 ERR_print_errors(bio_err
);