Add provider tests
authorRichard Levitte <levitte@openssl.org>
Wed, 20 Feb 2019 21:55:43 +0000 (22:55 +0100)
committerRichard Levitte <levitte@openssl.org>
Mon, 11 Mar 2019 19:40:13 +0000 (20:40 +0100)
Two tests are added, one that tests the internal API, the other tests
the public API.  Those two tests both test the same provider, which
acts both as a built-in provider and as a loadable provider module.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8287)

test/build.info
test/p_test.c [new file with mode: 0644]
test/provider_internal_test.c [new file with mode: 0644]
test/provider_test.c [new file with mode: 0644]
test/recipes/02-test_internal_provider.t [new file with mode: 0644]
test/recipes/04-test_provider.t [new file with mode: 0644]

index 4dd400f..f7ec8a2 100644 (file)
@@ -578,6 +578,29 @@ IF[{- !$disabled{tests} -}]
   SOURCE[context_internal_test]=context_internal_test.c
   INCLUDE[context_internal_test]=.. ../include ../apps/include
   DEPEND[context_internal_test]=../libcrypto.a libtestutil.a
+
+  PROGRAMS{noinst}=provider_internal_test
+  DEFINE[provider_internal_test]=PROVIDER_INIT_FUNCTION_NAME=p_test_init
+  SOURCE[provider_internal_test]=provider_internal_test.c p_test.c
+  INCLUDE[provider_internal_test]=../include ../apps/include
+  DEPEND[provider_internal_test]=../libcrypto.a libtestutil.a
+  PROGRAMS{noinst}=provider_test
+  DEFINE[provider_test]=PROVIDER_INIT_FUNCTION_NAME=p_test_init
+  SOURCE[provider_test]=provider_test.c p_test.c
+  INCLUDE[provider_test]=../include ../apps/include
+  DEPEND[provider_test]=../libcrypto.a libtestutil.a
+  IF[{- !$disabled{shared} -}]
+    MODULES{noinst}=p_test
+    SOURCE[p_test]=p_test.c
+    INCLUDE[p_test]=../include
+    IF[{- defined $target{shared_defflag} -}]
+      SOURCE[p_test]=p_test.ld
+      GENERATE[p_test.ld]=../util/providers.num
+    ENDIF
+  ELSE
+    DEFINE[provider_test]=OPENSSL_NO_SHARED
+    DEFINE[provider_internal_test]=OPENSSL_NO_SHARED
+  ENDIF
 ENDIF
 
 {-
diff --git a/test/p_test.c b/test/p_test.c
new file mode 100644 (file)
index 0000000..6dc0410
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 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
+ */
+
+/*
+ * This is a very simple provider that does absolutely nothing except respond
+ * to provider global parameter requests.  It does this by simply echoing back
+ * a parameter request it makes to the loading library.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * When built as an object file to link the application with, we get the
+ * init function name through the macro PROVIDER_INIT_FUNCTION_NAME.  If
+ * not defined, we use the standard init function name for the shared
+ * object form.
+ */
+#ifdef PROVIDER_INIT_FUNCTION_NAME
+# define OSSL_provider_init PROVIDER_INIT_FUNCTION_NAME
+#endif
+
+#include <openssl/core.h>
+#include <openssl/core_numbers.h>
+
+static OSSL_core_get_param_types_fn *c_get_param_types = NULL;
+static OSSL_core_get_params_fn *c_get_params = NULL;
+
+/* Tell the core what params we provide and what type they are */
+static const OSSL_ITEM p_param_types[] = {
+    { OSSL_PARAM_UTF8_STRING, "greeting" },
+    { 0, NULL }
+};
+
+static const OSSL_ITEM *p_get_param_types(const OSSL_PROVIDER *_)
+{
+    return p_param_types;
+}
+
+static int p_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
+{
+    const OSSL_PARAM *p = params;
+    int ok = 1;
+
+    for (; ok && p->key != NULL; p++) {
+        if (strcmp(p->key, "greeting") == 0) {
+            static char *opensslv = NULL;
+            static char *provname = NULL;
+            static OSSL_PARAM counter_request[] = {
+                { "openssl-version", OSSL_PARAM_UTF8_STRING_PTR,
+                  &opensslv, sizeof(&opensslv), NULL },
+                { "provider-name", OSSL_PARAM_UTF8_STRING_PTR,
+                  &provname, sizeof(&provname), NULL},
+                { NULL, 0, NULL, 0, NULL }
+            };
+            char buf[256];
+            size_t buf_l;
+
+            if (c_get_params(prov, counter_request)) {
+                const char *versionp = *(void **)counter_request[0].buffer;
+                const char *namep = *(void **)counter_request[1].buffer;
+                sprintf(buf, "Hello OpenSSL %.20s, greetings from %s!",
+                        versionp, namep);
+            } else {
+                sprintf(buf, "Howdy stranger...");
+            }
+
+            *p->return_size = buf_l = strlen(buf) + 1;
+            if (p->buffer_size >= buf_l)
+                strncpy(p->buffer, buf, buf_l);
+            else
+                ok = 0;
+        }
+    }
+    return ok;
+}
+
+static const OSSL_DISPATCH p_test_table[] = {
+    { OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))p_get_param_types },
+    { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))p_get_params },
+    { 0, NULL }
+};
+
+int OSSL_provider_init(const OSSL_PROVIDER *provider,
+                       const OSSL_DISPATCH *in,
+                       const OSSL_DISPATCH **out)
+{
+    for (; in->function_id != 0; in++) {
+        switch (in->function_id) {
+        case OSSL_FUNC_CORE_GET_PARAM_TYPES:
+            c_get_param_types = OSSL_get_core_get_param_types(in);
+            break;
+        case OSSL_FUNC_CORE_GET_PARAMS:
+            c_get_params = OSSL_get_core_get_params(in);
+            break;
+        default:
+            /* Just ignore anything we don't understand */
+            break;
+        }
+    }
+
+    *out = p_test_table;
+    return 1;
+}
diff --git a/test/provider_internal_test.c b/test/provider_internal_test.c
new file mode 100644 (file)
index 0000000..c423808
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2019 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 <stddef.h>
+#include "internal/provider.h"
+#include "testutil.h"
+
+extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME;
+
+static char buf[256];
+static size_t buf_l = 0;
+static OSSL_PARAM greeting_request[] = {
+    { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf), &buf_l },
+    { NULL, 0, NULL, 0, NULL }
+};
+
+static int test_provider(OSSL_PROVIDER *prov)
+{
+    const char *name = NULL;
+    const char *greeting = NULL;
+    char expected_greeting[256];
+    int ret = 0;
+
+    if (!TEST_ptr(name = ossl_provider_name(prov)))
+        return 0;
+
+    snprintf(expected_greeting, sizeof(expected_greeting),
+             "Hello OpenSSL %.20s, greetings from %s!",
+             OPENSSL_VERSION_STR, name);
+
+    ret =
+        TEST_true(ossl_provider_activate(prov))
+        && TEST_true(ossl_provider_get_params(prov, greeting_request))
+        && TEST_ptr(greeting = greeting_request[0].buffer)
+        && TEST_size_t_gt(greeting_request[0].buffer_size, 0)
+        && TEST_str_eq(greeting, expected_greeting);
+
+    ossl_provider_free(prov);
+    return ret;
+}
+
+static int test_builtin_provider(void)
+{
+    const char *name = "p_test_builtin";
+    OSSL_PROVIDER *prov = NULL;
+
+    return
+        TEST_ptr(prov =
+                 ossl_provider_new(NULL, name, PROVIDER_INIT_FUNCTION_NAME))
+        && test_provider(prov);
+}
+
+#ifndef OPENSSL_NO_SHARED
+static int test_loaded_provider(void)
+{
+    const char *name = "p_test";
+    OSSL_PROVIDER *prov = NULL;
+
+    return
+        TEST_ptr(prov = ossl_provider_new(NULL, name, NULL))
+        && test_provider(prov);
+}
+#endif
+
+int setup_tests(void)
+{
+    ADD_TEST(test_builtin_provider);
+#ifndef OPENSSL_NO_SHARED
+    ADD_TEST(test_loaded_provider);
+#endif
+    return 1;
+}
+
diff --git a/test/provider_test.c b/test/provider_test.c
new file mode 100644 (file)
index 0000000..738cd7b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2019 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 <stddef.h>
+#include <openssl/provider.h>
+#include "testutil.h"
+
+extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME;
+
+static char buf[256];
+static size_t buf_l = 0;
+static OSSL_PARAM greeting_request[] = {
+    { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf), &buf_l },
+    { NULL, 0, NULL, 0, NULL }
+};
+
+static int test_provider(const char *name)
+{
+    OSSL_PROVIDER *prov = NULL;
+    const char *greeting = NULL;
+    char expected_greeting[256];
+
+    snprintf(expected_greeting, sizeof(expected_greeting),
+             "Hello OpenSSL %.20s, greetings from %s!",
+             OPENSSL_VERSION_STR, name);
+
+    return
+        TEST_ptr(prov = OSSL_PROVIDER_load(NULL, name))
+        && TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
+        && TEST_ptr(greeting = greeting_request[0].buffer)
+        && TEST_size_t_gt(greeting_request[0].buffer_size, 0)
+        && TEST_str_eq(greeting, expected_greeting)
+        && TEST_true(OSSL_PROVIDER_unload(prov));
+}
+
+static int test_builtin_provider(void)
+{
+    const char *name = "p_test_builtin";
+
+    return
+        TEST_true(OSSL_PROVIDER_add_builtin(NULL, name,
+                                           PROVIDER_INIT_FUNCTION_NAME))
+        && test_provider(name);
+}
+
+#ifndef OPENSSL_NO_SHARED
+static int test_loaded_provider(void)
+{
+    const char *name = "p_test";
+
+    return test_provider(name);
+}
+#endif
+
+int setup_tests(void)
+{
+    ADD_TEST(test_builtin_provider);
+#ifndef OPENSSL_NO_SHARED
+    ADD_TEST(test_loaded_provider);
+#endif
+    return 1;
+}
+
diff --git a/test/recipes/02-test_internal_provider.t b/test/recipes/02-test_internal_provider.t
new file mode 100644 (file)
index 0000000..8275eb2
--- /dev/null
@@ -0,0 +1,18 @@
+#! /usr/bin/env perl
+# Copyright 2019 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
+
+use strict;
+use OpenSSL::Test qw(:DEFAULT bldtop_dir);
+use OpenSSL::Test::Simple;
+use OpenSSL::Test::Utils;
+
+setup("test_internal_provider");
+
+$ENV{"OPENSSL_MODULES"} = bldtop_dir("test");
+
+simple_test("test_internal_provider", "provider_internal_test");
diff --git a/test/recipes/04-test_provider.t b/test/recipes/04-test_provider.t
new file mode 100644 (file)
index 0000000..9195a42
--- /dev/null
@@ -0,0 +1,18 @@
+#! /usr/bin/env perl
+# Copyright 2019 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
+
+use strict;
+use OpenSSL::Test qw(:DEFAULT bldtop_dir);
+use OpenSSL::Test::Simple;
+use OpenSSL::Test::Utils;
+
+setup("test_provider");
+
+$ENV{"OPENSSL_MODULES"} = bldtop_dir("test");
+
+simple_test("test_provider", "provider_test");