Fix copyright year issues
[openssl.git] / test / filterprov.c
index 9fe6690e50801a2b857c0dfff01cb762c8b41966..e14c802b1df6080f80715c205280b18058e6a959 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-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
 
 #include <string.h>
 #include <openssl/core.h>
-#include <openssl/core_numbers.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
 
 struct filter_prov_globals_st {
-    OPENSSL_CTX *libctx;
+    OSSL_LIB_CTX *libctx;
     OSSL_PROVIDER *deflt;
     struct {
         int operation;
         OSSL_ALGORITHM alg[MAX_ALG_FILTERS + 1];
     } dispatch[MAX_FILTERS];
     int num_dispatch;
+    int no_cache;
+    unsigned long int query_count;
+    int error;
 };
 
 static struct filter_prov_globals_st ourglobals;
@@ -40,17 +40,18 @@ static struct filter_prov_globals_st ourglobals;
 static struct filter_prov_globals_st *get_globals(void)
 {
     /*
-     * Ideally we'd like to store this in the OPENSSL_CTX so that we can have
+     * Ideally we'd like to store this in the OSSL_LIB_CTX so that we can have
      * more than one instance of the filter provider at a time. But for now we
      * just make it simple.
      */
     return &ourglobals;
 }
 
-static OSSL_provider_gettable_params_fn filter_gettable_params;
-static OSSL_provider_get_params_fn filter_get_params;
-static OSSL_provider_query_operation_fn filter_query;
-static OSSL_provider_teardown_fn filter_teardown;
+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)
 {
@@ -66,6 +67,14 @@ static int filter_get_params(void *provctx, OSSL_PARAM params[])
     return OSSL_PROVIDER_get_params(globs->deflt, params);
 }
 
+static int filter_get_capabilities(void *provctx, const char *capability,
+                                   OSSL_CALLBACK *cb, void *arg)
+{
+    struct filter_prov_globals_st *globs = get_globals();
+
+    return OSSL_PROVIDER_get_capabilities(globs->deflt, capability, cb, arg);
+}
+
 static const OSSL_ALGORITHM *filter_query(void *provctx,
                                           int operation_id,
                                           int *no_cache)
@@ -73,9 +82,10 @@ static const OSSL_ALGORITHM *filter_query(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 = 0;
+            *no_cache = globs->no_cache;
             return globs->dispatch[i].alg;
         }
     }
@@ -84,12 +94,30 @@ static const OSSL_ALGORITHM *filter_query(void *provctx,
     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);
-    OPENSSL_CTX_free(globs->libctx);
+    OSSL_LIB_CTX_free(globs->libctx);
+    memset(globs, 0, sizeof(*globs));
 }
 
 /* Functions we provide to the core */
@@ -97,6 +125,8 @@ static const OSSL_DISPATCH filter_dispatch_table[] = {
     { 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 }
 };
@@ -107,7 +137,7 @@ int filter_provider_init(const OSSL_CORE_HANDLE *handle,
                          void **provctx)
 {
     memset(&ourglobals, 0, sizeof(ourglobals));
-    ourglobals.libctx = OPENSSL_CTX_new();
+    ourglobals.libctx = OSSL_LIB_CTX_new();
     if (ourglobals.libctx == NULL)
         goto err;
 
@@ -121,7 +151,7 @@ int filter_provider_init(const OSSL_CORE_HANDLE *handle,
 
  err:
     OSSL_PROVIDER_unload(ourglobals.deflt);
-    OPENSSL_CTX_free(ourglobals.libctx);
+    OSSL_LIB_CTX_free(ourglobals.libctx);
     return 0;
 }
 
@@ -147,10 +177,6 @@ int filter_provider_set_filter(int operation, const char *filterstr)
     if (filterstrtmp == NULL)
         goto err;
 
-    /* We don't support no_cache */
-    if (no_cache)
-        goto err;
-
     /* Nothing to filter */
     if (provalgs == NULL)
         goto err;
@@ -158,7 +184,7 @@ int filter_provider_set_filter(int operation, const char *filterstr)
     if (globs->num_dispatch >= MAX_FILTERS)
         goto err;
 
-    for (name = filterstrtmp; !last; name = sep + 1) {
+    for (name = filterstrtmp; !last; name = (sep == NULL ? NULL : sep + 1)) {
         sep = strstr(name, ":");
         if (sep != NULL)
             *sep = '\0';
@@ -190,10 +216,23 @@ int filter_provider_set_filter(int operation, const char *filterstr)
     }
 
     globs->dispatch[globs->num_dispatch].operation = operation;
+    globs->no_cache = no_cache;
     globs->num_dispatch++;
 
     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;
+}