From 64129008fb822758778f7dd29cec6a0a4582e4d2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 14 Sep 2023 09:25:30 -0400 Subject: [PATCH] Add Test to verify open_ex password checking works Signed-off-by: Simo Sorce Reviewed-by: Dmitry Belyavskiy Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/20131) --- test/fake_rsaprov.c | 46 ++++++++++++++++++++++++++- test/fake_rsaprov.h | 2 ++ test/provider_pkey_test.c | 66 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c index 9bc463b2c8..c1b8e28286 100644 --- a/test/fake_rsaprov.c +++ b/test/fake_rsaprov.c @@ -525,6 +525,7 @@ static const OSSL_ALGORITHM fake_rsa_sig_algs[] = { }; static OSSL_FUNC_store_open_fn fake_rsa_st_open; +static OSSL_FUNC_store_open_ex_fn fake_rsa_st_open_ex; static OSSL_FUNC_store_settable_ctx_params_fn fake_rsa_st_settable_ctx_params; static OSSL_FUNC_store_set_ctx_params_fn fake_rsa_st_set_ctx_params; static OSSL_FUNC_store_load_fn fake_rsa_st_load; @@ -533,8 +534,13 @@ static OSSL_FUNC_store_close_fn fake_rsa_st_close; static OSSL_FUNC_store_delete_fn fake_rsa_st_delete; static const char fake_rsa_scheme[] = "fake_rsa:"; +static const char fake_rsa_openpwtest[] = "fake_rsa:openpwtest"; +static const char fake_rsa_prompt[] = "Fake Prompt Info"; -static void *fake_rsa_st_open(void *provctx, const char *uri) +static void *fake_rsa_st_open_ex(void *provctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, + void *pw_cbarg) { unsigned char *storectx = NULL; @@ -542,10 +548,47 @@ static void *fake_rsa_st_open(void *provctx, const char *uri) if (strncmp(uri, fake_rsa_scheme, sizeof(fake_rsa_scheme) - 1) != 0) return NULL; + if (strncmp(uri, fake_rsa_openpwtest, + sizeof(fake_rsa_openpwtest) - 1) == 0) { + const char *pw_check = FAKE_PASSPHRASE; + char fakepw[sizeof(FAKE_PASSPHRASE) + 1] = { 0 }; + size_t fakepw_len = 0; + OSSL_PARAM pw_params[2] = { + OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, + (void *)fake_rsa_prompt, + sizeof(fake_rsa_prompt) - 1), + OSSL_PARAM_END, + }; + + if (pw_cb == NULL) { + return NULL; + } + + if (!pw_cb(fakepw, sizeof(fakepw), &fakepw_len, pw_params, pw_cbarg)) { + TEST_info("fake_rsa_open_ex failed passphrase callback"); + return NULL; + } + if (strncmp(pw_check, fakepw, sizeof(pw_check) - 1) != 0) { + TEST_info("fake_rsa_open_ex failed passphrase check"); + return NULL; + } + } + storectx = OPENSSL_zalloc(1); if (!TEST_ptr(storectx)) return NULL; + TEST_info("fake_rsa_open_ex called"); + + return storectx; +} + +static void *fake_rsa_st_open(void *provctx, const char *uri) +{ + unsigned char *storectx = NULL; + + storectx = fake_rsa_st_open_ex(provctx, uri, NULL, NULL, NULL); + TEST_info("fake_rsa_open called"); return storectx; @@ -643,6 +686,7 @@ static int fake_rsa_st_close(void *loaderctx) static const OSSL_DISPATCH fake_rsa_store_funcs[] = { { OSSL_FUNC_STORE_OPEN, (void (*)(void))fake_rsa_st_open }, + { OSSL_FUNC_STORE_OPEN_EX, (void (*)(void))fake_rsa_st_open_ex }, { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, (void (*)(void))fake_rsa_st_settable_ctx_params }, { OSSL_FUNC_STORE_SET_CTX_PARAMS, (void (*)(void))fake_rsa_st_set_ctx_params }, diff --git a/test/fake_rsaprov.h b/test/fake_rsaprov.h index 53056fa59f..9c353b386f 100644 --- a/test/fake_rsaprov.h +++ b/test/fake_rsaprov.h @@ -9,6 +9,8 @@ #include +#define FAKE_PASSPHRASE "Passphrase Testing" + /* Fake RSA provider implementation */ OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx); void fake_rsa_finish(OSSL_PROVIDER *p); diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c index 09b060642b..7d5fcfa647 100644 --- a/test/provider_pkey_test.c +++ b/test/provider_pkey_test.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "testutil.h" #include "fake_rsaprov.h" @@ -359,6 +360,70 @@ end: return ret; } +static int fake_pw_read_string(UI *ui, UI_STRING *uis) +{ + const char *passphrase = FAKE_PASSPHRASE; + + if (UI_get_string_type(uis) == UIT_PROMPT) { + UI_set_result(ui, uis, passphrase); + return 1; + } + + return 0; +} + +static int test_pkey_store_open_ex(void) +{ + OSSL_PROVIDER *deflt = NULL; + OSSL_PROVIDER *fake_rsa = NULL; + int ret = 0; + EVP_PKEY *pkey = NULL; + OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_CTX *ctx = NULL; + const char *propq = "?provider=fake-rsa"; + UI_METHOD *ui_method = NULL; + + /* It's important to load the default provider first for this test */ + if (!TEST_ptr(deflt = OSSL_PROVIDER_load(libctx, "default"))) + goto end; + + if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) + goto end; + + if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", + propq))) + goto end; + + OSSL_STORE_LOADER_free(loader); + + if (!TEST_ptr(ui_method= UI_create_method("PW Callbacks"))) + goto end; + + if (UI_method_set_reader(ui_method, fake_pw_read_string)) + goto end; + + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, propq, + ui_method, NULL, NULL, NULL, NULL))) + goto end; + + /* retry w/o ui_method to ensure we actually enter pw checks and fail */ + OSSL_STORE_close(ctx); + if (!TEST_ptr_null(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, + propq, NULL, NULL, NULL, NULL, + NULL))) + goto end; + + ret = 1; + +end: + UI_destroy_method(ui_method); + fake_rsa_finish(fake_rsa); + OSSL_PROVIDER_unload(deflt); + OSSL_STORE_close(ctx); + EVP_PKEY_free(pkey); + return ret; +} + int setup_tests(void) { libctx = OSSL_LIB_CTX_new(); @@ -370,6 +435,7 @@ int setup_tests(void) ADD_TEST(test_pkey_eq); ADD_ALL_TESTS(test_pkey_store, 2); ADD_TEST(test_pkey_delete); + ADD_TEST(test_pkey_store_open_ex); return 1; }