data->fn(provider, thismap, no_store, data->data);
}
}
+ ossl_provider_unquery_operation(provider, cur_operation, map);
/* Do we fulfill post-conditions? */
if (data->post == NULL) {
return ossl_provider_query_operation(prov, operation_id, no_cache);
}
+void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ const OSSL_ALGORITHM *algs)
+{
+ ossl_provider_unquery_operation(prov, operation_id, algs);
+}
+
void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov)
{
return ossl_provider_prov_ctx(prov);
OSSL_FUNC_provider_get_capabilities_fn *get_capabilities;
OSSL_FUNC_provider_self_test_fn *self_test;
OSSL_FUNC_provider_query_operation_fn *query_operation;
+ OSSL_FUNC_provider_unquery_operation_fn *unquery_operation;
/*
* Cache of bit to indicate of query_operation() has been called on
prov->query_operation =
OSSL_FUNC_provider_query_operation(provider_dispatch);
break;
+ case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION:
+ prov->unquery_operation =
+ OSSL_FUNC_provider_unquery_operation(provider_dispatch);
+ break;
#ifndef OPENSSL_NO_ERR
# ifndef FIPS_MODULE
case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS:
return res;
}
+void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ const OSSL_ALGORITHM *algs)
+{
+ if (prov->unquery_operation != NULL)
+ prov->unquery_operation(prov->provctx, operation_id, algs);
+}
+
int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum)
{
size_t byte = bitnum / 8;
ossl_provider_module_name, ossl_provider_module_path,
ossl_provider_libctx,
ossl_provider_teardown, ossl_provider_gettable_params,
-ossl_provider_get_params, ossl_provider_query_operation,
+ossl_provider_get_params,
+ossl_provider_query_operation, ossl_provider_unquery_operation,
ossl_provider_set_operation_bit, ossl_provider_test_operation_bit,
ossl_provider_get_capabilities
- internal provider routines
const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
int operation_id,
int *no_cache);
+ void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ const OSSL_ALGORITHM *algs);
int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum);
int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum,
It should return an array of I<OSSL_ALGORITHM> for the given
I<operation_id>.
+ossl_provider_unquery_operation() informs the provider that the result of
+ossl_provider_query_operation() is no longer going to be directly accessed and
+that all relevant information has been copied.
+
ossl_provider_set_operation_bit() registers a 1 for operation I<bitnum>
in a bitstring that's internal to I<provider>.
OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_try_load, OSSL_PROVIDER_unload,
OSSL_PROVIDER_available, OSSL_PROVIDER_do_all,
OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params,
-OSSL_PROVIDER_query_operation, OSSL_PROVIDER_get0_provider_ctx,
-OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name,
+OSSL_PROVIDER_query_operation, OSSL_PROVIDER_unquery_operation,
+OSSL_PROVIDER_get0_provider_ctx, OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name,
OSSL_PROVIDER_get_capabilities, OSSL_PROVIDER_self_test
- provider routines
const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov,
int operation_id,
int *no_cache);
+ void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ const OSSL_ALGORITHM *algs);
void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov);
int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name,
NULL OSSL_ALGORITHM entry. This is considered a low-level function that most
applications should not need to call.
+OSSL_PROVIDER_unquery_operation() calls the provider's I<unquery_operation>
+function (see L<provider(7)>), if the provider has one. This is considered a
+low-level function that most applications should not need to call.
+
OSSL_PROVIDER_get0_provider_ctx() returns the provider context for the given
provider. The provider context is an opaque handle set by the provider itself
and is passed back to the provider by libcrypto in various function calls.
const OSSL_ALGORITHM *provider_query_operation(void *provctx,
int operation_id,
const int *no_store);
+ void provider_unquery_operation(void *provctx, int operation_id,
+ const OSSL_ALGORITHM *algs);
const OSSL_ITEM *provider_get_reason_strings(void *provctx);
int provider_get_capabilities(void *provctx, const char *capability,
OSSL_CALLBACK *cb, void *arg);
provider_gettable_params OSSL_FUNC_PROVIDER_GETTABLE_PARAMS
provider_get_params OSSL_FUNC_PROVIDER_GET_PARAMS
provider_query_operation OSSL_FUNC_PROVIDER_QUERY_OPERATION
+ provider_unquery_operation OSSL_FUNC_PROVIDER_UNQUERY_OPERATION
provider_get_reason_strings OSSL_FUNC_PROVIDER_GET_REASON_STRINGS
provider_get_capabilities OSSL_FUNC_PROVIDER_GET_CAPABILITIES
provider_self_test OSSL_FUNC_PROVIDER_SELF_TEST
setting I<*no_store> to 0 (core may store a reference) or 1 (core may
not store a reference).
+provider_unquery_operation() informs the provider that the result of a
+provider_query_operation() is no longer directly required and that the function
+pointers have been copied. The I<operation_id> should match that passed to
+provider_query_operation() and I<algs> should be its return value.
+
provider_get_reason_strings() should return a constant B<OSSL_ITEM>
array that provides reason strings for reason codes the provider may
use when reporting errors using core_put_error().
const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
int operation_id,
int *no_cache);
+void ossl_provider_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id,
+ const OSSL_ALGORITHM *algs);
/* Cache of bits to see if we already queried an operation */
int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum);
# define OSSL_FUNC_PROVIDER_QUERY_OPERATION 1027
OSSL_CORE_MAKE_FUNC(const OSSL_ALGORITHM *,provider_query_operation,
(void *provctx, int operation_id, int *no_store))
-# define OSSL_FUNC_PROVIDER_GET_REASON_STRINGS 1028
+# define OSSL_FUNC_PROVIDER_UNQUERY_OPERATION 1028
+OSSL_CORE_MAKE_FUNC(void, provider_unquery_operation,
+ (void *provctx, int operation_id, const OSSL_ALGORITHM *))
+# define OSSL_FUNC_PROVIDER_GET_REASON_STRINGS 1029
OSSL_CORE_MAKE_FUNC(const OSSL_ITEM *,provider_get_reason_strings,
(void *provctx))
-# define OSSL_FUNC_PROVIDER_GET_CAPABILITIES 1029
+# define OSSL_FUNC_PROVIDER_GET_CAPABILITIES 1030
OSSL_CORE_MAKE_FUNC(int, provider_get_capabilities, (void *provctx,
const char *capability, OSSL_CALLBACK *cb, void *arg))
-# define OSSL_FUNC_PROVIDER_SELF_TEST 1030
+# define OSSL_FUNC_PROVIDER_SELF_TEST 1031
OSSL_CORE_MAKE_FUNC(int, provider_self_test, (void *provctx))
/* Operations */
const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov,
int operation_id,
int *no_cache);
+void OSSL_PROVIDER_unquery_operation(const OSSL_PROVIDER *prov,
+ int operation_id, const OSSL_ALGORITHM *algs);
void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov);
/* Add a built in providers */
#include <string.h>
#include <openssl/core.h>
-#include <openssl/core_dispatch.h>
#include <openssl/provider.h>
#include <openssl/crypto.h>
-
-OSSL_provider_init_fn filter_provider_init;
-
-int filter_provider_set_filter(int operation, const char *name);
+#include "testutil.h"
+#include "filterprov.h"
#define MAX_FILTERS 10
#define MAX_ALG_FILTERS 5
} dispatch[MAX_FILTERS];
int num_dispatch;
int no_cache;
+ unsigned long int query_count;
+ int error;
};
static struct filter_prov_globals_st ourglobals;
static OSSL_FUNC_provider_gettable_params_fn filter_gettable_params;
static OSSL_FUNC_provider_get_params_fn filter_get_params;
static OSSL_FUNC_provider_query_operation_fn filter_query;
+static OSSL_FUNC_provider_unquery_operation_fn filter_unquery;
static OSSL_FUNC_provider_teardown_fn filter_teardown;
static const OSSL_PARAM *filter_gettable_params(void *provctx)
struct filter_prov_globals_st *globs = get_globals();
int i;
+ globs->query_count++;
for (i = 0; i < globs->num_dispatch; i++) {
if (globs->dispatch[i].operation == operation_id) {
*no_cache = globs->no_cache;
return OSSL_PROVIDER_query_operation(globs->deflt, operation_id, no_cache);
}
+static void filter_unquery(void *provctx, int operation_id,
+ const OSSL_ALGORITHM *algs)
+{
+ struct filter_prov_globals_st *globs = get_globals();
+ int i;
+
+ if (!TEST_ulong_gt(globs->query_count, 0))
+ globs->error = 1;
+ else
+ globs->query_count--;
+
+ for (i = 0; i < globs->num_dispatch; i++)
+ if (globs->dispatch[i].alg == algs)
+ return;
+ OSSL_PROVIDER_unquery_operation(globs->deflt, operation_id, algs);
+}
+
static void filter_teardown(void *provctx)
{
struct filter_prov_globals_st *globs = get_globals();
OSSL_PROVIDER_unload(globs->deflt);
OSSL_LIB_CTX_free(globs->libctx);
+ memset(globs, 0, sizeof(*globs));
}
/* Functions we provide to the core */
{ OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))filter_gettable_params },
{ OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))filter_get_params },
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))filter_query },
+ { OSSL_FUNC_PROVIDER_UNQUERY_OPERATION, (void (*)(void))filter_unquery },
{ OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))filter_get_capabilities },
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))filter_teardown },
{ 0, NULL }
ret = 1;
err:
+ OSSL_PROVIDER_unquery_operation(globs->deflt, operation, provalgs);
OPENSSL_free(filterstrtmp);
return ret;
}
+
+/*
+ * Test if a filter provider is in a clean finishing state.
+ * If it is return 1, otherwise return 0.
+ */
+int filter_provider_check_clean_finish(void)
+{
+ struct filter_prov_globals_st *globs = get_globals();
+
+ return TEST_ulong_eq(globs->query_count, 0) && !globs->error;
+}
--- /dev/null
+/*
+ * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core_dispatch.h>
+
+OSSL_provider_init_fn filter_provider_init;
+int filter_provider_set_filter(int operation, const char *name);
+int filter_provider_check_clean_finish(void);
#include "internal/nelem.h"
#include "internal/ktls.h"
#include "../ssl/ssl_local.h"
+#include "filterprov.h"
#undef OSSL_NO_USABLE_TLS1_3
#if defined(OPENSSL_NO_TLS1_3) \
# define OSSL_NO_USABLE_TLS1_3
#endif
-/* Defined in filterprov.c */
-OSSL_provider_init_fn filter_provider_init;
-int filter_provider_set_filter(int operation, const char *name);
-
/* Defined in tls-provider.c */
int tls_provider_init(const OSSL_CORE_HANDLE *handle,
const OSSL_DISPATCH *in,
: NID_rsassaPss))
goto end;
- testresult = 1;
+ testresult = filter_provider_check_clean_finish();
end:
SSL_free(serverssl);
EVP_PKEY_eq ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_parameters_eq ? 3_0_0 EXIST::FUNCTION:
OSSL_PROVIDER_query_operation ? 3_0_0 EXIST::FUNCTION:
+OSSL_PROVIDER_unquery_operation ? 3_0_0 EXIST::FUNCTION:
OSSL_PROVIDER_get0_provider_ctx ? 3_0_0 EXIST::FUNCTION:
OSSL_PROVIDER_get_capabilities ? 3_0_0 EXIST::FUNCTION:
EC_GROUP_new_by_curve_name_ex ? 3_0_0 EXIST::FUNCTION:EC