+/*
+ * Load those types of credentials for which the result pointer is not NULL.
+ * Reads from stdio if uri is NULL and maybe_stdin is nonzero.
+ * For each type the first credential found in the store is loaded.
+ * May yield partial result even if rv == 0.
+ */
+int load_key_cert_crl(const char *uri, int maybe_stdin,
+ const char *pass, const char *desc,
+ EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl)
+{
+ PW_CB_DATA uidata;
+ OSSL_STORE_CTX *ctx = NULL;
+ int ret = 0;
+ /* TODO make use of the engine reference 'eng' when loading pkeys */
+
+ if (ppkey != NULL)
+ *ppkey = NULL;
+ if (pcert != NULL)
+ *pcert = NULL;
+ if (pcrl != NULL)
+ *pcrl = NULL;
+
+ if (desc == NULL)
+ desc = "key/certificate/CRL";
+ uidata.password = pass;
+ uidata.prompt_info = uri;
+
+ if (uri == NULL) {
+ BIO *bio;
+
+ if (!maybe_stdin) {
+ BIO_printf(bio_err, "No filename or uri specified for loading %s\n",
+ desc);
+ goto end;
+ }
+ unbuffer(stdin);
+ bio = BIO_new_fp(stdin, 0);
+ if (bio != NULL)
+ ctx = OSSL_STORE_attach(bio, NULL, "file", NULL,
+ get_ui_method(), &uidata, NULL, NULL);
+ uri = "<stdin>";
+ } else {
+ ctx = OSSL_STORE_open(uri, get_ui_method(), &uidata, NULL, NULL);
+ }
+ if (ctx == NULL) {
+ BIO_printf(bio_err, "Could not open file or uri %s for loading %s\n",
+ uri, desc);
+ goto end;
+ }
+
+ for (;;) {
+ OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
+ int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info);
+ const char *infostr =
+ info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
+ int err = 0;
+
+ if (info == NULL) {
+ if (OSSL_STORE_eof(ctx))
+ ret = 1;
+ break;
+ }
+
+ switch (type) {
+ case OSSL_STORE_INFO_PKEY:
+ if (ppkey != NULL && *ppkey == NULL)
+ err = ((*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) == NULL);
+ break;
+ case OSSL_STORE_INFO_CERT:
+ if (pcert != NULL && *pcert == NULL)
+ err = ((*pcert = OSSL_STORE_INFO_get1_CERT(info)) == NULL);
+ break;
+ case OSSL_STORE_INFO_CRL:
+ if (pcrl != NULL && *pcrl == NULL)
+ err = ((*pcrl = OSSL_STORE_INFO_get1_CRL(info)) == NULL);
+ break;
+ default:
+ /* skip any other type */
+ break;
+ }
+ OSSL_STORE_INFO_free(info);
+ if (err) {
+ BIO_printf(bio_err, "Could not read %s of %s from %s\n",
+ infostr, desc, uri);
+ break;
+ }
+ }
+
+ end:
+ OSSL_STORE_close(ctx);
+ if (!ret)
+ ERR_print_errors(bio_err);
+ return ret;
+}
+
+