diff --git a/CMakeLists.txt b/CMakeLists.txt index 7958247c..fad726df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,3 +89,6 @@ add_subdirectory(oqsprov) # Testing enable_testing() add_subdirectory(test) + +# Examples +add_subdirectory(examples) diff --git a/CONFIGURE.md b/CONFIGURE.md index afae2735..dff28861 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -91,6 +91,9 @@ void load_oqs_provider(OSSL_LIB_CTX *libctx) { > **Warning** > `OQS_PROVIDER_BUILD_STATIC` and `BUILD_SHARED_LIBS` are mutually exclusive. +See [`examples/static_oqsprovider.c`](examples/static_oqsprovider.c) for a complete +example of how to load oqsprovider using `OSSL_PROVIDER_add_builtin`. + ## Convenience build script options For anyone interested in building the complete software stack diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..43ec0ca8 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,7 @@ +if (OQS_PROVIDER_BUILD_STATIC) + add_executable(example_static_oqsprovider static_oqsprovider.c) + target_link_libraries(example_static_oqsprovider PRIVATE ${OPENSSL_CRYPTO_LIBRARY} oqsprovider) + targets_set_static_provider(example_static_oqsprovider) + add_test(NAME test_example_static_oqsprovider + COMMAND example_static_oqsprovider) +endif() diff --git a/examples/static_oqsprovider.c b/examples/static_oqsprovider.c new file mode 100644 index 00000000..14285340 --- /dev/null +++ b/examples/static_oqsprovider.c @@ -0,0 +1,95 @@ +/** + * \file + * \brief Example of how to load oqsprovider when compiled as a static library + * `using OSSL_PROVIDER_add_builtin`. + */ + +#include + +#include +#include +#include + +/** \brief The initialization function of oqsprovider. */ +extern OSSL_provider_init_fn oqs_provider_init; + +/** \brief Name of the oqsprovider. */ +static const char *kOQSProviderName = "oqsprovider"; + +/** \brief Tries to load the oqsprovider named "oqsprovider". + * + * \param libctx Context of the OpenSSL library in which to load the + * oqsprovider. + * + * \returns 0 if success, else -1. */ +static int load_oqs_provider(OSSL_LIB_CTX *libctx) +{ + OSSL_PROVIDER *provider; + int ret; + + ret = OSSL_PROVIDER_available(libctx, kOQSProviderName); + if (ret != 0) { + fprintf(stderr, + "`OSSL_PROVIDER_available` returned %i, but 0 was expected\n", + ret); + return -1; + } + + ret = OSSL_PROVIDER_add_builtin(libctx, kOQSProviderName, + oqs_provider_init); + if (ret != 1) { + fprintf(stderr, + "`OSSL_PROVIDER_add_builtin` failed with returned code %i\n", + ret); + return -1; + } + + provider = OSSL_PROVIDER_load(libctx, kOQSProviderName); + if (provider == NULL) { + fputs("`OSSL_PROVIDER_load` failed\n", stderr); + return -1; + } + + ret = OSSL_PROVIDER_available(libctx, kOQSProviderName); + if (ret != 1) { + fprintf(stderr, + "`OSSL_PROVIDER_available` returned %i, but 0 was expected\n", + ret); + return -1; + } + + ret = OSSL_PROVIDER_self_test(provider); + if (ret != 1) { + fprintf(stderr, + "`OSSL_PROVIDER_self_test` failed with returned code %i\n", + ret); + return -1; + } + + return 0; +} + +int main() +{ + OSSL_LIB_CTX *libctx; + int ret; + + libctx = OSSL_LIB_CTX_new(); + if (libctx == NULL) { + fputs("`OSSL_LIB_CTX_new` failed. Cannot initialize OpenSSL.\n", + stderr); + return 1; + } + + ret = load_oqs_provider(libctx); + if (ret != 0) { + fputs("`load_oqs_provider` failed. Dumping OpenSSL error queue.\n", + stderr); + ERR_print_errors_fp(stderr); + return 2; + } + + OSSL_LIB_CTX_free(libctx); + + return 0; +}