#include <stdlib.h>
#include <string.h>
+#include "e_os.h"
+
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/store.h>
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data)
{
- const OSSL_STORE_LOADER *loader;
+ const OSSL_STORE_LOADER *loader = NULL;
OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
OSSL_STORE_CTX *ctx = NULL;
- char scheme_copy[256], *p;
-
+ char scheme_copy[256], *p, *schemes[2];
+ size_t schemes_n = 0;
+ size_t i;
+
+ /*
+ * Put the file scheme first. If the uri does represent an existing file,
+ * possible device name and all, then it should be loaded. Only a failed
+ * attempt at loading a local file should have us try something else.
+ */
+ schemes[schemes_n++] = "file";
+
+ /*
+ * Now, check if we have something that looks like a scheme, and add it
+ * as a second scheme. However, also check if there's an authority start
+ * (://), because that will invalidate the previous file scheme. Also,
+ * check that this isn't actually the file scheme, as there's no point
+ * going through that one twice!
+ */
OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy));
if ((p = strchr(scheme_copy, ':')) != NULL) {
- *p = '\0';
- p = scheme_copy;
- } else {
- p = "file";
+ *p++ = '\0';
+ if (strcasecmp(scheme_copy, "file") != 0) {
+ if (strncmp(p, "//", 2) == 0)
+ schemes_n--; /* Invalidate the file scheme */
+ schemes[schemes_n++] = scheme_copy;
+ }
}
- if ((loader = ossl_store_get0_loader_int(p)) == NULL
- || (loader_ctx = loader->open(loader, uri, ui_method, ui_data)) == NULL)
+ /* Try each scheme until we find one that could open the URI */
+ for (i = 0; loader_ctx == NULL && i < schemes_n; i++) {
+ if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL)
+ loader_ctx = loader->open(loader, uri, ui_method, ui_data);
+ }
+ if (loader_ctx == NULL)
goto done;
+
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE);
goto done;
/*
* Functions to generate OSSL_STORE_INFOs, one function for each type we
- * support having in them. Along with each of them, one macro that
- * can be used to determine what types are supported.
+ * support having in them as well as a generic constructor.
*
* In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
* and will therefore be freed when the OSSL_STORE_INFO is freed.