Commit 6d872729a0 for openssl.org

commit 6d872729a08df87b9f65e9b87867515a4ae0fe9c
Author: Jakub Jelen <jjelen@redhat.com>
Date:   Tue Nov 10 16:18:30 2026 +0100

    test: add test for OSSL_STORE SKEY references

    Extend the fake store provider to support returning SKEY references
    and implement basic key management callbacks.
    Add test_fake_store_skey_ref to ossl_store_test to ensure symmetric
    keys can be queried and loaded properly via OSSL_STORE.

    Assisted-by: Vimini:Gemini-3.8-Flash
    Signed-off-by: Jakub Jelen <jjelen@redhat.com>
    Reviewed-by: Simo Sorce <simo@redhat.com>
    Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    Merge-date: Thu Nov 12 10:18:01 2026
    Merged-from: https://github.com/openssl/openssl/pull/33643

diff --git a/test/fake_storeprov.c b/test/fake_storeprov.c
index e0cfbbdb34..84c4defd25 100644
--- a/test/fake_storeprov.c
+++ b/test/fake_storeprov.c
@@ -29,6 +29,7 @@ struct fake_store_ctx_st {
     int remaining;
     int fail_params;
     int expected_type;
+    int is_skey_ref;
 };

 static unsigned int seen_params = 0;
@@ -76,6 +77,7 @@ static void *fake_store_open(void *provctx, const char *uri)
         return NULL;
     ctx->remaining = strcmp(cmd, FAKE_STORE_CMD_TWO_NAMES) == 0 ? 2 : 1;
     ctx->fail_params = strcmp(cmd, FAKE_STORE_CMD_PARAMS_FAIL) == 0;
+    ctx->is_skey_ref = strcmp(cmd, FAKE_STORE_CMD_SKEY_REF) == 0;
     return ctx;
 }

@@ -155,24 +157,41 @@ static int fake_store_load(void *loaderctx,
     OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
 {
     struct fake_store_ctx_st *ctx = loaderctx;
-    OSSL_PARAM params[4];
-    int object_type = OSSL_OBJECT_NAME;
-    char name[16], desc[16];

     if (ctx->remaining <= 0)
         return 0;
-    snprintf(name, sizeof(name), "name%d", ctx->remaining);
-    snprintf(desc, sizeof(desc), "desc%d", ctx->remaining);
     ctx->remaining--;

-    params[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
-    params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA,
-        name, 0);
-    params[2] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DESC,
-        desc, 0);
-    params[3] = OSSL_PARAM_construct_end();
-
-    return object_cb(params, object_cbarg);
+    if (ctx->is_skey_ref) {
+        OSSL_PARAM params[4];
+        static const char dummy_ref[] = "fake-skey-ref";
+        int object_type = OSSL_OBJECT_SKEY;
+
+        params[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
+        params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+            OSSL_SKEY_TYPE_GENERIC, 0);
+        params[2] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
+            (void *)dummy_ref, sizeof(dummy_ref));
+        params[3] = OSSL_PARAM_construct_end();
+
+        return object_cb(params, object_cbarg);
+    } else {
+        OSSL_PARAM params[4];
+        int object_type = OSSL_OBJECT_NAME;
+        char name[16], desc[16];
+
+        snprintf(name, sizeof(name), "name%d", ctx->remaining + 1);
+        snprintf(desc, sizeof(desc), "desc%d", ctx->remaining + 1);
+
+        params[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
+        params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA,
+            name, 0);
+        params[2] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DESC,
+            desc, 0);
+        params[3] = OSSL_PARAM_construct_end();
+
+        return object_cb(params, object_cbarg);
+    }
 }

 static int fake_store_eof(void *loaderctx)
@@ -232,12 +251,55 @@ static const OSSL_ALGORITHM fake_store_store_algs[] = {
     { NULL, NULL, NULL, NULL }
 };

+static void fake_skeymgmt_free(void *keydata)
+{
+    OPENSSL_free(keydata);
+}
+
+static void *fake_skeymgmt_import(void *provctx, int selection, const OSSL_PARAM *params)
+{
+    const OSSL_PARAM *p;
+    const void *ref = NULL;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE);
+    if (p == NULL || !OSSL_PARAM_get_octet_string_ptr(p, &ref, NULL))
+        return NULL;
+
+    return OPENSSL_malloc(1);
+}
+
+static int fake_skeymgmt_export(void *keydata, int selection,
+    OSSL_CALLBACK *param_callback, void *cbarg)
+{
+    OSSL_PARAM params[1] = { OSSL_PARAM_END };
+
+    return param_callback(params, cbarg);
+}
+
+static const OSSL_DISPATCH fake_store_skeymgmt_funcs[] = {
+    { OSSL_FUNC_SKEYMGMT_FREE, (void (*)(void))fake_skeymgmt_free },
+    { OSSL_FUNC_SKEYMGMT_IMPORT, (void (*)(void))fake_skeymgmt_import },
+    { OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))fake_skeymgmt_export },
+    OSSL_DISPATCH_END
+};
+
+static const OSSL_ALGORITHM fake_store_skeymgmt_algs[] = {
+    { OSSL_SKEY_TYPE_GENERIC, FAKE_STORE_FETCH_PROPS, fake_store_skeymgmt_funcs,
+        "Fake store Generic Key Management" },
+    { NULL, NULL, NULL, NULL }
+};
+
 static const OSSL_ALGORITHM *fake_store_query(void *provctx, int operation_id,
     int *no_cache)
 {
-    *no_cache = 0;
-    if (operation_id == OSSL_OP_STORE)
+    switch (operation_id) {
+    case OSSL_OP_STORE:
+        *no_cache = 0;
         return fake_store_store_algs;
+    case OSSL_OP_SKEYMGMT:
+        *no_cache = 1;
+        return fake_store_skeymgmt_algs;
+    }
     return NULL;
 }

diff --git a/test/fake_storeprov.h b/test/fake_storeprov.h
index ab5bdbeae0..2fa691b3c9 100644
--- a/test/fake_storeprov.h
+++ b/test/fake_storeprov.h
@@ -27,6 +27,7 @@ void fake_store_finish(OSSL_PROVIDER *p);
 #define FAKE_STORE_CMD_TWO_NAMES "two-names"
 #define FAKE_STORE_CMD_OPEN_FAIL "open-fail"
 #define FAKE_STORE_CMD_PARAMS_FAIL "params-fail"
+#define FAKE_STORE_CMD_SKEY_REF "skey-ref"

 /* Bitmask of ctx params the fake loader has observed */
 #define FAKE_STORE_SEEN_EXPECT (1u << 0)
diff --git a/test/ossl_store_test.c b/test/ossl_store_test.c
index 5453fe454c..6cc79ff09d 100644
--- a/test/ossl_store_test.c
+++ b/test/ossl_store_test.c
@@ -664,6 +664,51 @@ static int test_fake_store_delete(void)
         0);
 }

+static int test_fake_store_skey_ref(void)
+{
+    OSSL_STORE_CTX *sctx = NULL;
+    OSSL_STORE_INFO *info = NULL;
+    EVP_SKEY *skey = NULL;
+    EVP_SKEY *skey2 = NULL;
+    int ret = 0;
+
+    if (!TEST_ptr(sctx = OSSL_STORE_open_ex(
+                      FAKE_STORE_SCHEME ":" FAKE_STORE_CMD_SKEY_REF,
+                      fake_libctx, FAKE_STORE_FETCH_PROPS,
+                      NULL, NULL, NULL, NULL, NULL))
+        || !TEST_true(OSSL_STORE_expect(sctx, OSSL_STORE_INFO_SKEY))
+        || !TEST_ptr(info = OSSL_STORE_load(sctx)))
+        goto err;
+
+    if (!TEST_int_eq(OSSL_STORE_INFO_get_type(info), OSSL_STORE_INFO_SKEY)
+        || !TEST_ptr(skey = OSSL_STORE_INFO_get0_SKEY(info))
+        || !TEST_ptr(skey2 = OSSL_STORE_INFO_get1_SKEY(info))
+        || !TEST_ptr(OSSL_STORE_INFO_get0_data(OSSL_STORE_INFO_SKEY, info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get0_PARAMS(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get1_PARAMS(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get0_PUBKEY(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get1_PUBKEY(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get0_PKEY(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get1_PKEY(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get0_CERT(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get1_CERT(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get0_CRL(info))
+        || !TEST_ptr_null(OSSL_STORE_INFO_get1_CRL(info)))
+        goto err;
+
+    if (!TEST_true(OSSL_STORE_eof(sctx))
+        || !TEST_ptr_null(OSSL_STORE_load(sctx))
+        || !TEST_false(OSSL_STORE_error(sctx)))
+        goto err;
+
+    ret = 1;
+err:
+    EVP_SKEY_free(skey2);
+    OSSL_STORE_INFO_free(info);
+    OSSL_STORE_close(sctx);
+    return ret;
+}
+
 const OPTIONS *test_get_options(void)
 {
     static const OPTIONS test_options[] = {
@@ -736,6 +781,7 @@ int setup_tests(void)
     ADD_TEST(test_fake_store_post_process);
     ADD_TEST(test_fake_store_attach);
     ADD_TEST(test_fake_store_delete);
+    ADD_TEST(test_fake_store_skey_ref);
     return 1;
 }