Add test for try_key_ref() fallback handling
authorTomas Mraz <tomas@openssl.org>
Thu, 7 Apr 2022 14:48:41 +0000 (16:48 +0200)
committerTomas Mraz <tomas@openssl.org>
Tue, 28 Jun 2022 15:54:56 +0000 (17:54 +0200)
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17554)

test/fake_rsaprov.c
test/provider_pkey_test.c

index d2503320f4cb929deaf7857366e8b38cd51d6645..8f82f5987c61d18e418aed219cdb3f200d9772cc 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <string.h>
 #include <openssl/core_names.h>
+#include <openssl/core_object.h>
 #include <openssl/rand.h>
 #include <openssl/provider.h>
 #include "testutil.h"
@@ -21,6 +22,7 @@ static OSSL_FUNC_keymgmt_has_fn fake_rsa_keymgmt_has;
 static OSSL_FUNC_keymgmt_query_operation_name_fn fake_rsa_keymgmt_query;
 static OSSL_FUNC_keymgmt_import_fn fake_rsa_keymgmt_import;
 static OSSL_FUNC_keymgmt_import_types_fn fake_rsa_keymgmt_imptypes;
+static OSSL_FUNC_keymgmt_load_fn fake_rsa_keymgmt_load;
 
 static int has_selection;
 static int imptypes_selection;
@@ -93,6 +95,23 @@ static const OSSL_PARAM *fake_rsa_keymgmt_imptypes(int selection)
     return fake_rsa_import_key_types;
 }
 
+static void *fake_rsa_keymgmt_load(const void *reference, size_t reference_sz)
+{
+    unsigned char *key = NULL;
+
+    if (reference_sz != sizeof(key))
+        return NULL;
+
+    key = *(unsigned char **)reference;
+    if (*key != 1)
+        return NULL;
+
+    /* detach the reference */
+    *(unsigned char **)reference = NULL;
+
+    return key;
+}
+
 static void *fake_rsa_gen_init(void *provctx, int selection,
                                const OSSL_PARAM params[])
 {
@@ -137,6 +156,7 @@ static const OSSL_DISPATCH fake_rsa_keymgmt_funcs[] = {
     { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))fake_rsa_keymgmt_import },
     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES,
         (void (*)(void))fake_rsa_keymgmt_imptypes },
+    { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))fake_rsa_keymgmt_load },
     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))fake_rsa_gen_init },
     { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))fake_rsa_gen },
     { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))fake_rsa_gen_cleanup },
@@ -222,6 +242,124 @@ static const OSSL_ALGORITHM fake_rsa_sig_algs[] = {
     { NULL, NULL, NULL, NULL }
 };
 
+static OSSL_FUNC_store_open_fn fake_rsa_st_open;
+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;
+static OSSL_FUNC_store_eof_fn fake_rsa_st_eof;
+static OSSL_FUNC_store_close_fn fake_rsa_st_close;
+
+static const char fake_rsa_scheme[] = "fake_rsa:";
+
+static void *fake_rsa_st_open(void *provctx, const char *uri)
+{
+    unsigned char *storectx = NULL;
+
+    /* First check whether the uri is ours */
+    if (strncmp(uri, fake_rsa_scheme, sizeof(fake_rsa_scheme) - 1) != 0)
+        return NULL;
+
+    storectx = OPENSSL_zalloc(1);
+    TEST_ptr(storectx);
+
+    TEST_info("fake_rsa_open called");
+
+    return storectx;
+}
+
+static const OSSL_PARAM *fake_rsa_st_settable_ctx_params(void *provctx)
+{
+    static const OSSL_PARAM known_settable_ctx_params[] = {
+        OSSL_PARAM_END
+    };
+    return known_settable_ctx_params;
+}
+
+static int fake_rsa_st_set_ctx_params(void *loaderctx,
+                                      const OSSL_PARAM params[])
+{
+    return 1;
+}
+
+static int fake_rsa_st_load(void *loaderctx,
+                            OSSL_CALLBACK *object_cb, void *object_cbarg,
+                            OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+    unsigned char *storectx = loaderctx;
+    OSSL_PARAM params[4];
+    int object_type = OSSL_OBJECT_PKEY;
+    void *key = NULL;
+    int rv = 0;
+
+    switch (*storectx) {
+    case 0:
+        /* Construct a new key using our keymgmt functions */
+        if (!TEST_ptr(key = fake_rsa_keymgmt_new(NULL)))
+            break;
+        if (!TEST_int_gt(fake_rsa_keymgmt_import(key, 0, NULL), 0))
+            break;
+        params[0] =
+            OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
+        params[1] =
+            OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+                                             "RSA", 0);
+        /* The address of the key becomes the octet string */
+        params[2] =
+            OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
+                                              &key, sizeof(key));
+        params[3] = OSSL_PARAM_construct_end();
+        rv = object_cb(params, object_cbarg);
+        *storectx = 1;
+        break;
+
+    case 2:
+        TEST_info("fake_rsa_load() called in error state");
+        break;
+
+    default:
+        TEST_info("fake_rsa_load() called in eof state");
+        break;
+    }
+
+    TEST_info("fake_rsa_load called - rv: %d", rv);
+
+    if (rv == 0) {
+        fake_rsa_keymgmt_free(key);
+        *storectx = 2;
+    }
+    return rv;
+}
+
+static int fake_rsa_st_eof(void *loaderctx)
+{
+    unsigned char *storectx = loaderctx;
+
+    /* just one key for now in the fake_rsa store */
+    return *storectx != 0;
+}
+
+static int fake_rsa_st_close(void *loaderctx)
+{
+    OPENSSL_free(loaderctx);
+    return 1;
+}
+
+static const OSSL_DISPATCH fake_rsa_store_funcs[] = {
+    { OSSL_FUNC_STORE_OPEN, (void (*)(void))fake_rsa_st_open },
+    { 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 },
+    { OSSL_FUNC_STORE_LOAD, (void (*)(void))fake_rsa_st_load },
+    { OSSL_FUNC_STORE_EOF, (void (*)(void))fake_rsa_st_eof },
+    { OSSL_FUNC_STORE_CLOSE, (void (*)(void))fake_rsa_st_close },
+    { 0, NULL },
+};
+
+static const OSSL_ALGORITHM fake_rsa_store_algs[] = {
+    { "fake_rsa", "provider=fake-rsa", fake_rsa_store_funcs },
+    { NULL, NULL, NULL }
+};
+
 static const OSSL_ALGORITHM *fake_rsa_query(void *provctx,
                                             int operation_id,
                                             int *no_cache)
@@ -233,6 +371,9 @@ static const OSSL_ALGORITHM *fake_rsa_query(void *provctx,
 
     case OSSL_OP_KEYMGMT:
         return fake_rsa_keymgmt_algs;
+
+    case OSSL_OP_STORE:
+        return fake_rsa_store_algs;
     }
     return NULL;
 }
index dc59326182ed0a61be266505bd6af068eb18ad82..5c398398f4b853f87f093332e47cb024c30f6401 100644 (file)
@@ -13,6 +13,7 @@
 #include <openssl/params.h>
 #include <openssl/core_names.h>
 #include <openssl/evp.h>
+#include <openssl/store.h>
 #include "testutil.h"
 #include "fake_rsaprov.h"
 
@@ -175,6 +176,57 @@ end:
     return ret;
 }
 
+static int test_pkey_store(int idx)
+{
+    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;
+    OSSL_STORE_INFO *info;
+    const char *propq = idx == 0 ? "?provider=fake-rsa"
+                                 : "?provider=default";
+
+    /* 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(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq,
+                                           NULL, NULL, NULL, NULL, NULL)))
+        goto end;
+
+    while (!OSSL_STORE_eof(ctx)
+           && (info = OSSL_STORE_load(ctx)) != NULL
+           && pkey == NULL) {
+        if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY)
+            pkey = OSSL_STORE_INFO_get1_PKEY(info);
+        OSSL_STORE_INFO_free(info);
+        info = NULL;
+    }
+
+    if (!TEST_ptr(pkey) || !TEST_int_eq(EVP_PKEY_is_a(pkey, "RSA"), 1))
+        goto end;
+
+    ret = 1;
+
+end:
+    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();
@@ -183,6 +235,7 @@ int setup_tests(void)
 
     ADD_TEST(test_pkey_sig);
     ADD_TEST(test_alternative_keygen_init);
+    ADD_ALL_TESTS(test_pkey_store, 2);
 
     return 1;
 }