]> wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
Making a gost provider - Add the provider foundation
authorRichard Levitte <richard@levitte.org>
Sat, 13 Feb 2021 13:50:49 +0000 (14:50 +0100)
committerDmitry Belyavskiy <beldmit@users.noreply.github.com>
Mon, 11 Oct 2021 16:34:09 +0000 (19:34 +0300)
This adds the source to get a minimal provider that provides...
nothing.

.cirrus.yml
.github/workflows/ci.yml
.github/workflows/codeql-analysis.yml
.gitmodules [new file with mode: 0644]
CMakeLists.txt
e_gost_err.c
gost_lcl.h
gost_prov.c [new file with mode: 0644]
gost_prov.h [new file with mode: 0644]
libprov [new submodule]

index 7a0c3c9322062110b28d257ee4163097bfc5691a..d2058558483ea721fe8605ea1725a29bbe20b61c 100644 (file)
@@ -8,6 +8,8 @@ FreeBSD_task:
   install_script:
     - pkg install -y git cmake p5-App-cpanminus gdb pkgconf
     - sudo cpanm --notest Test2::V0
+  update_git_script:
+    - git submodule update --recursive --init
   script:
     - git clone --depth 1 -b ${OPENSSL_BRANCH} https://github.com/openssl/openssl.git
     - cd openssl
index 14718dcac98881b6b53230e5df32944c3f42d40d..8baf3ba1bcb48236783ac243962a65c18ab93ae9 100644 (file)
@@ -10,6 +10,8 @@ jobs:
         runs-on: ubuntu-20.04
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -19,6 +21,8 @@ jobs:
             CC: clang
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -28,6 +32,8 @@ jobs:
             USE_RPATH:
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -37,6 +43,8 @@ jobs:
             OPENSSL_BRANCH: master
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -47,6 +55,8 @@ jobs:
             USE_RPATH:
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -57,6 +67,8 @@ jobs:
             ASAN: -DASAN=1
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -68,6 +80,8 @@ jobs:
             USE_RPATH:
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
@@ -80,6 +94,8 @@ jobs:
             APT_INSTALL: gcc-multilib
         steps:
             - uses: actions/checkout@v2
+              with:
+                  submodules: true
             - run: .github/before_script.sh
             - run: .github/script.sh
 
index ec6665d73665b648e9f22903d5d696cd4ead823f..194a08da4a4151bb6a8d5db35bd735260eeb4757 100644 (file)
@@ -27,6 +27,8 @@ jobs:
         # We must fetch at least the immediate parents so that if this is
         # a pull request then we can checkout the head.
         fetch-depth: 2
+        # gost-engine has submodules
+        submodules: true
 
     # If this run was triggered by a pull request event, then checkout
     # the head of the pull request instead of the merge commit.
diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..f40e730
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "libprov"]
+       path = libprov
+       url = https://github.com/provider-corner/libprov.git
index ff1a71d7acc61c7acb0675c8bb68a9d68a1566d7..b6476e7bc684f0974772f2192c57933ae74333da 100644 (file)
@@ -197,6 +197,10 @@ set(GOST_ENGINE_SOURCE_FILES
         gost_eng.c
         )
 
+set(GOST_PROV_SOURCE_FILES
+        gost_prov.c
+        )
+
 set(TEST_ENVIRONMENT
         CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
         PERL5LIB=${CMAKE_CURRENT_SOURCE_DIR}/test
@@ -205,6 +209,7 @@ set(TEST_ENVIRONMENT
         OPENSSL_CRYPTO_LIBRARY=${OPENSSL_CRYPTO_LIBRARY}
         OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/test/engine.cnf
         )
+
 add_executable(test_digest test_digest.c)
 target_link_libraries(test_digest OpenSSL::Crypto)
 add_test(NAME digest COMMAND test_digest)
@@ -307,8 +312,31 @@ set_target_properties(lib_gost_engine PROPERTIES
   COMPILE_DEFINITIONS "BUILDING_ENGINE_AS_LIBRARY"
   PUBLIC_HEADER gost-engine.h
   OUTPUT_NAME "gost")
-target_link_libraries(lib_gost_engine PRIVATE gost_core)
-
+target_link_libraries(lib_gost_engine PRIVATE gost_core gost_err)
+
+
+# The GOST provider uses this
+add_subdirectory(libprov)
+
+# The GOST provider in module form
+add_library(gost_prov MODULE
+  ${GOST_PROV_SOURCE_FILES} ${GOST_ENGINE_SOURCE_FILES}
+  )
+set_target_properties(gost_prov PROPERTIES
+  PREFIX "" OUTPUT_NAME "gostprov" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}
+  COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;OPENSSL_NO_DYNAMIC_ENGINE"
+  )
+target_link_libraries(gost_prov PRIVATE gost_core libprov)
+
+# The GOST provider in library form
+add_library(lib_gost_prov SHARED
+  ${GOST_PROV_SOURCE_FILES} ${GOST_ENGINE_SOURCE_FILES}
+  )
+set_target_properties(lib_gost_prov PROPERTIES
+  OUTPUT_NAME "gostprov"
+  COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;BUILDING_PROVIDER_AS_LIBRARY;OPENSSL_NO_DYNAMIC_ENGINE"
+  )
+target_link_libraries(lib_gost_prov PRIVATE gost_core libprov)
 
 set(GOST_SUM_SOURCE_FILES
         gostsum.c
index c71272e2c4fe09805f0e7c460f6576ba96c1125c..51599ca0cdbe28a70f9164028d7978e6a0e1808a 100644 (file)
@@ -176,6 +176,7 @@ static ERR_STRING_DATA GOST_str_reasons[] = {
 
 #endif
 
+#ifndef GOST_PROV
 static int lib_code = 0;
 static int error_loaded = 0;
 
@@ -220,3 +221,4 @@ void ERR_GOST_error(int function, int reason, char *file, int line)
     ERR_set_debug(file, line, NULL);
 #endif
 }
+#endif
index c518ed0333e92a981f3a4c08ace9110d201714f9..4801e17aeb14086e49a6ac10e0c7cf3978720f41 100644 (file)
@@ -10,6 +10,7 @@
  *         OpenSSL 0.9.9 libraries required to compile and use        *
  *                              this code                             *
  **********************************************************************/
+# include <openssl/core.h>
 # include <openssl/bn.h>
 # include <openssl/evp.h>
 # include <openssl/asn1t.h>
diff --git a/gost_prov.c b/gost_prov.c
new file mode 100644 (file)
index 0000000..fe65c4d
--- /dev/null
@@ -0,0 +1,144 @@
+/**********************************************************************
+ *                 gost_prov.c - The provider itself                  *
+ *                                                                    *
+ *      Copyright (c) 2021 Richard Levitte <richard@levitte.org>      *
+ *     This file is distributed under the same license as OpenSSL     *
+ *                                                                    *
+ *                Requires OpenSSL 3.0 for compilation                *
+ **********************************************************************/
+
+#include <openssl/core_dispatch.h>
+#include "gost_prov.h"
+#include "gost_lcl.h"
+#include "prov/err.h"           /* libprov err functions */
+
+/*********************************************************************
+ *
+ *  Errors
+ *
+ *****/
+
+/*
+ * Ugly hack, to get the errors generated by mkerr.pl.  This should ideally
+ * be replaced with a local OSSL_ITEM list of < number, string > pairs as
+ * reason strings, but for now, we will simply use GOST_str_reasons.
+ * Fortunately, the ERR_STRING_DATA structure is compatible with OSSL_ITEM,
+ * so we can return it directly.
+ */
+static struct proverr_functions_st *err_handle;
+#define GOST_PROV
+#include "e_gost_err.c"
+void ERR_GOST_error(int function, int reason, char *file, int line)
+{
+    proverr_new_error(err_handle);
+    proverr_set_error_debug(err_handle, file, line, NULL);
+    proverr_set_error(err_handle, reason, NULL);
+}
+
+/*********************************************************************
+ *
+ *  Provider context
+ *
+ *****/
+
+static void provider_ctx_free(PROV_CTX *ctx)
+{
+    if (ctx != NULL) {
+        ENGINE_free(ctx->e);
+        proverr_free_handle(ctx->proverr_handle);
+        OSSL_LIB_CTX_free(ctx->libctx);
+    }
+    free(ctx);
+}
+
+extern int populate_gost_engine(ENGINE *e);
+static PROV_CTX *provider_ctx_new(const OSSL_CORE_HANDLE *core,
+                                  const OSSL_DISPATCH *in)
+{
+    PROV_CTX *ctx;
+
+    if ((ctx = malloc(sizeof(*ctx))) != NULL
+        && (ctx->proverr_handle = proverr_new_handle(core, in)) != NULL
+        && (ctx->libctx = OSSL_LIB_CTX_new()) != NULL
+        && (ctx->e = ENGINE_new()) != NULL
+        && populate_gost_engine(ctx->e)) {
+        ctx->core_handle = core;
+
+        /* Ugly hack */
+        err_handle = ctx->proverr_handle;
+    } else {
+        provider_ctx_free(ctx);
+        ctx = NULL;
+    }
+    return ctx;
+}
+
+/*********************************************************************
+ *
+ *  Setup
+ *
+ *****/
+
+typedef void (*fptr_t)(void);
+
+/* The function that returns the appropriate algorithm table per operation */
+static const OSSL_ALGORITHM *gost_operation(void *vprovctx,
+                                                int operation_id,
+                                                const int *no_cache)
+{
+    return NULL;
+}
+
+static int gost_get_params(void *provctx, OSSL_PARAM *params)
+{
+    return 1;
+}
+
+static const OSSL_ITEM *gost_get_reason_strings(void *provctx)
+{
+#if 0
+    return reason_strings;
+#endif
+    return (OSSL_ITEM *)GOST_str_reasons;
+}
+
+/* The function that tears down this provider */
+static void gost_teardown(void *vprovctx)
+{
+    provider_ctx_free(vprovctx);
+}
+
+/* The base dispatch table */
+static const OSSL_DISPATCH provider_functions[] = {
+    { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (fptr_t)gost_operation },
+    { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (fptr_t)gost_get_reason_strings },
+    { OSSL_FUNC_PROVIDER_GET_PARAMS, (fptr_t)gost_get_params },
+    { OSSL_FUNC_PROVIDER_TEARDOWN, (fptr_t)gost_teardown },
+    { 0, NULL }
+};
+
+struct prov_ctx_st {
+    void *core_handle;
+    struct proverr_functions_st *err_handle;
+};
+
+#ifdef BUILDING_PROVIDER_AS_LIBRARY
+/*
+ * This allows the provider to be built in library form.  In this case, the
+ * application must add it explicitly like this:
+ *
+ * OSSL_PROVIDER_add_builtin(NULL, "gost", GOST_provider_init);
+ */
+# define OSSL_provider_init GOST_provider_init
+#endif
+
+int OSSL_provider_init(const OSSL_CORE_HANDLE *core,
+                       const OSSL_DISPATCH *in,
+                       const OSSL_DISPATCH **out,
+                       void **vprovctx)
+{
+    if ((*vprovctx = provider_ctx_new(core, in)) == NULL)
+        return 0;
+    *out = provider_functions;
+    return 1;
+}
diff --git a/gost_prov.h b/gost_prov.h
new file mode 100644 (file)
index 0000000..c7f6e66
--- /dev/null
@@ -0,0 +1,27 @@
+/**********************************************************************
+ *                 gost_prov.h - The provider itself                  *
+ *                                                                    *
+ *      Copyright (c) 2021 Richard Levitte <richard@levitte.org>      *
+ *     This file is distributed under the same license as OpenSSL     *
+ *                                                                    *
+ *                Requires OpenSSL 3.0 for compilation                *
+ **********************************************************************/
+
+#include <openssl/core.h>
+#include <openssl/engine.h>
+
+struct provider_ctx_st {
+    OSSL_LIB_CTX *libctx;
+    const OSSL_CORE_HANDLE *core_handle;
+    struct proverr_functions_st *proverr_handle;
+
+    /*
+     * "internal" GOST engine, which is the implementation that all the
+     * provider functions will use to access the crypto functionality.
+     * This is pure hackery, but allows us to quickly wrap all the ENGINE
+     * function with provider wrappers.  There is no other supported way
+     * to do this.
+     */
+    ENGINE *e;
+};
+typedef struct provider_ctx_st PROV_CTX;
diff --git a/libprov b/libprov
new file mode 160000 (submodule)
index 0000000..0f87843
--- /dev/null
+++ b/libprov
@@ -0,0 +1 @@
+Subproject commit 0f87843c0b85f325bdac7e0341946fc97d5d9d2d