From c60b5723194952d2e4bbfc1e4a3eb07b7581edd9 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Thu, 17 Sep 2020 09:48:29 +0200 Subject: [PATCH] STORE: clear err after ossl_store_get0_loader_int This commit clears the error that might have been set when ossl_store_get0_loader_int has been called as it will try to retrieve a loader for the scheme on an empty store, which will cause the error OSSL_STORE_R_UNREGISTERED_SCHEME to be set. The motivation for this after returning from ossl_store_get0_loader_int, OSSL_STORE_attach will continue and try to fetch a OSSL_STORE_LOADER from the provider. Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/12901) --- crypto/store/store_lib.c | 15 ++++++++++++++- test/ossl_store_test.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 671852cea22..c59c508be1e 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -930,6 +930,7 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, scheme = "file"; OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); + ERR_set_mark(); #ifndef OPENSSL_NO_DEPRECATED_3_0 if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) loader_ctx = loader->attach(loader, bp, libctx, propq, @@ -963,24 +964,36 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, loader = fetched_loader; } - if (loader_ctx == NULL) + if (loader_ctx == NULL) { + ERR_clear_last_mark(); return NULL; + } if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + ERR_clear_last_mark(); ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } if (ui_method != NULL && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { + ERR_clear_last_mark(); OPENSSL_free(ctx); return NULL; } + ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; ctx->post_process = post_process; ctx->post_process_data = post_process_data; + /* + * ossl_store_get0_loader_int will raise an error if the loader for the + * the scheme cannot be retrieved. But if a loader was successfully + * fetched then we remove this error from the error stack. + */ + ERR_pop_to_mark(); + return ctx; } diff --git a/test/ossl_store_test.c b/test/ossl_store_test.c index f48c282b2e9..7424aed0dd5 100644 --- a/test/ossl_store_test.c +++ b/test/ossl_store_test.c @@ -132,6 +132,33 @@ static int test_store_get_params(int idx) return 1; } +/* + * This test verifies that calling OSSL_STORE_ATTACH does not set an + * "unregistered scheme" error when called. + */ +static int test_store_attach_unregistered_scheme(void) +{ + int ret; + OSSL_STORE_CTX *store_ctx; + OSSL_PROVIDER *provider; + OSSL_LIB_CTX *libctx; + BIO *bio; + libctx = OSSL_LIB_CTX_new(); + provider = OSSL_PROVIDER_load(libctx, "default"); + bio = BIO_new_file("test/certs/sm2-root.crt", "r"); + + ret = TEST_ptr(store_ctx = OSSL_STORE_attach(bio, "file", libctx, NULL, + NULL, NULL, NULL, NULL)) && + TEST_int_ne(ERR_GET_LIB(ERR_peek_error()), ERR_LIB_OSSL_STORE) && + TEST_int_ne(ERR_GET_REASON(ERR_peek_error()), + OSSL_STORE_R_UNREGISTERED_SCHEME); + + BIO_free(bio); + OSSL_STORE_close(store_ctx); + OSSL_PROVIDER_unload(provider); + OSSL_LIB_CTX_free(libctx); + return ret; +} const OPTIONS *test_get_options(void) { @@ -172,5 +199,6 @@ int setup_tests(void) ADD_TEST(test_store_open); ADD_TEST(test_store_search_by_key_fingerprint_fail); ADD_ALL_TESTS(test_store_get_params, 3); + ADD_TEST(test_store_attach_unregistered_scheme); return 1; } -- 2.47.2