X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fstore%2Fstore_lib.c;h=b982e9c7532bce3c459b496b0dd86d66c580ae33;hp=91faae20c5f986c7ce1fd0182d9e67c4881c9e76;hb=baa77e075538b3d849b5120b3b60f0caca15a803;hpb=6e2f49b38429d9df00ed12ade60e3de3b9ba43b3 diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 91faae20c5..b982e9c753 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -10,6 +10,8 @@ #include #include +#include "e_os.h" + #include #include #include @@ -31,22 +33,45 @@ OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, 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; @@ -129,8 +154,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx) /* * 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.