Replumbing: add functionality to set provider parameters
authorRichard Levitte <levitte@openssl.org>
Thu, 21 Mar 2019 07:44:06 +0000 (08:44 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 3 Apr 2019 09:42:48 +0000 (11:42 +0200)
Provider parameters are parameters set by the core that the provider
can retrieve.  The primary use it to support making OpenSSL
configuration data available to the provider.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8549)

crypto/cpt_err.c
crypto/err/openssl.txt
crypto/provider_core.c
include/internal/provider.h
include/openssl/cryptoerr.h

index 3c3265dce5f788af8a05a708c249ecd19d67da43..cca80378554c103462fd0704d9ffa379b69fad56 100644 (file)
@@ -50,8 +50,12 @@ static const ERR_STRING_DATA CRYPTO_str_functs[] = {
      "OSSL_PROVIDER_add_builtin"},
     {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ACTIVATE, 0),
      "ossl_provider_activate"},
+    {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, 0),
+     "ossl_provider_add_parameter"},
     {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_NEW, 0),
      "ossl_provider_new"},
+    {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH, 0),
+     "ossl_provider_set_module_path"},
     {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_HMAC_INIT, 0), "pkey_hmac_init"},
     {ERR_PACK(ERR_LIB_CRYPTO, CRYPTO_F_PKEY_POLY1305_INIT, 0),
      "pkey_poly1305_init"},
index 8808b25f56c3a75597f77e2e0b87057acdd34732..a3f3d48ce8194d4628a2bca1f9e78dd7894a4bcb 100644 (file)
@@ -392,7 +392,9 @@ CRYPTO_F_OPENSSL_SK_DEEP_COPY:127:OPENSSL_sk_deep_copy
 CRYPTO_F_OPENSSL_SK_DUP:128:OPENSSL_sk_dup
 CRYPTO_F_OSSL_PROVIDER_ACTIVATE:130:ossl_provider_activate
 CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN:132:OSSL_PROVIDER_add_builtin
+CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER:139:ossl_provider_add_parameter
 CRYPTO_F_OSSL_PROVIDER_NEW:131:ossl_provider_new
+CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH:140:ossl_provider_set_module_path
 CRYPTO_F_PKEY_HMAC_INIT:123:pkey_hmac_init
 CRYPTO_F_PKEY_POLY1305_INIT:124:pkey_poly1305_init
 CRYPTO_F_PKEY_SIPHASH_INIT:125:pkey_siphash_init
index 7a184a7d67e8f207b35243ea1de3bf86d95b74ad..9f4c0170457a956ea2cd615882ac872648d5d0fb 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <openssl/core.h>
 #include <openssl/core_numbers.h>
+#include <openssl/params.h>
 #include <openssl/opensslv.h>
 #include "internal/cryptlib.h"
 #include "internal/nelem.h"
@@ -25,6 +26,12 @@ static OSSL_PROVIDER *provider_new(const char *name,
  * =========================
  */
 
+typedef struct {
+    char *name;
+    char *value;
+} INFOPAIR;
+DEFINE_STACK_OF(INFOPAIR)
+
 struct provider_store_st;        /* Forward declaration */
 
 struct ossl_provider_st {
@@ -36,8 +43,10 @@ struct ossl_provider_st {
     CRYPTO_REF_COUNT refcnt;
     CRYPTO_RWLOCK *refcnt_lock;  /* For the ref counter */
     char *name;
+    char *path;
     DSO *module;
     OSSL_provider_init_fn *init_function;
+    STACK_OF(INFOPAIR) *parameters;
     struct provider_store_st *store; /* The store this instance belongs to */
 
     /* Provider side functions */
@@ -243,6 +252,13 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
     return prov;
 }
 
+static void free_infopair(INFOPAIR *pair)
+{
+    OPENSSL_free(pair->name);
+    OPENSSL_free(pair->value);
+    OPENSSL_free(pair);
+}
+
 void ossl_provider_free(OSSL_PROVIDER *prov)
 {
     if (prov != NULL) {
@@ -270,6 +286,8 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
         if (ref == 0) {
             DSO_free(prov->module);
             OPENSSL_free(prov->name);
+            OPENSSL_free(prov->path);
+            sk_INFOPAIR_pop_free(prov->parameters, free_infopair);
 #ifndef HAVE_ATOMICS
             CRYPTO_THREAD_lock_free(prov->refcnt_lock);
 #endif
@@ -278,6 +296,40 @@ void ossl_provider_free(OSSL_PROVIDER *prov)
     }
 }
 
+/* Setters */
+int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path)
+{
+    OPENSSL_free(prov->path);
+    if (module_path == NULL)
+        return 1;
+    if ((prov->path = OPENSSL_strdup(module_path)) != NULL)
+        return 1;
+    CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int ossl_provider_add_parameter(OSSL_PROVIDER *prov,
+                                const char *name, const char *value)
+{
+    INFOPAIR *pair = NULL;
+
+    if ((pair = OPENSSL_zalloc(sizeof(*pair))) != NULL
+        && (prov->parameters != NULL
+            || (prov->parameters = sk_INFOPAIR_new_null()) != NULL)
+        && (pair->name = OPENSSL_strdup(name)) != NULL
+        && (pair->value = OPENSSL_strdup(value)) != NULL
+        && sk_INFOPAIR_push(prov->parameters, pair) > 0)
+        return 1;
+
+    if (pair != NULL) {
+        OPENSSL_free(pair->name);
+        OPENSSL_free(pair->value);
+        OPENSSL_free(pair);
+    }
+    CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
 /*
  * Provider activation.
  *
@@ -310,8 +362,9 @@ static int provider_activate(OSSL_PROVIDER *prov)
      */
     if (prov->init_function == NULL) {
         if (prov->module == NULL) {
-            char *platform_module_name = NULL;
-            char *module_path = NULL;
+            char *allocated_path = NULL;
+            const char *module_path = NULL;
+            char *merged_path = NULL;
             const char *load_dir = ossl_safe_getenv("OPENSSL_MODULES");
 
             if ((prov->module = DSO_new()) == NULL) {
@@ -324,19 +377,22 @@ static int provider_activate(OSSL_PROVIDER *prov)
 
             DSO_ctrl(prov->module, DSO_CTRL_SET_FLAGS,
                      DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL);
-            if ((platform_module_name =
-                 DSO_convert_filename(prov->module, prov->name)) == NULL
-                || (module_path =
-                    DSO_merge(prov->module, platform_module_name,
-                              load_dir)) == NULL
-                || DSO_load(prov->module, module_path, NULL,
-                            DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == NULL) {
+
+            module_path = prov->path;
+            if (module_path == NULL)
+                module_path = allocated_path =
+                    DSO_convert_filename(prov->module, prov->name);
+            if (module_path != NULL)
+                merged_path = DSO_merge(prov->module, module_path, load_dir);
+
+            if (merged_path == NULL
+                || (DSO_load(prov->module, merged_path, NULL, 0)) == NULL) {
                 DSO_free(prov->module);
                 prov->module = NULL;
             }
 
-            OPENSSL_free(platform_module_name);
-            OPENSSL_free(module_path);
+            OPENSSL_free(merged_path);
+            OPENSSL_free(allocated_path);
         }
 
         if (prov->module != NULL)
@@ -565,17 +621,21 @@ static const OSSL_ITEM *core_get_param_types(const OSSL_PROVIDER *prov)
 static int core_get_params(const OSSL_PROVIDER *prov, const OSSL_PARAM params[])
 {
     int i;
+    const OSSL_PARAM *p;
 
-    for (i = 0; params[i].key != NULL; i++) {
-        if (strcmp(params[i].key, "openssl-version") == 0) {
-            *(void **)params[i].data = OPENSSL_VERSION_STR;
-            if (params[i].return_size)
-                *params[i].return_size = sizeof(OPENSSL_VERSION_STR);
-        } else if (strcmp(params[i].key, "provider-name") == 0) {
-            *(void **)params[i].data = prov->name;
-            if (params[i].return_size)
-                *params[i].return_size = strlen(prov->name) + 1;
-        }
+    if ((p = OSSL_PARAM_locate(params, "openssl-version")) != NULL)
+        OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR);
+    if ((p = OSSL_PARAM_locate(params, "provider-name")) != NULL)
+        OSSL_PARAM_set_utf8_ptr(p, prov->name);
+
+    if (prov->parameters == NULL)
+        return 1;
+
+    for (i = 0; i < sk_INFOPAIR_num(prov->parameters); i++) {
+        INFOPAIR *pair = sk_INFOPAIR_value(prov->parameters, i);
+
+        if ((p = OSSL_PARAM_locate(params, pair->name)) != NULL)
+            OSSL_PARAM_set_utf8_ptr(p, pair->value);
     }
 
     return 1;
index 8af20a7cfe2cd97d21fee58dc0bda97df1ad558b..abd5ec4392835b89784bb224a59e5ef09d857844 100644 (file)
@@ -33,8 +33,10 @@ int ossl_provider_upref(OSSL_PROVIDER *prov);
 void ossl_provider_free(OSSL_PROVIDER *prov);
 
 /* Setters */
-int ossl_provider_add_module_location(OSSL_PROVIDER *prov, const char *loc);
 int ossl_provider_set_fallback(OSSL_PROVIDER *prov);
+int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path);
+int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name,
+                                const char *value);
 
 /*
  * Activate the Provider
index b38b272a24af636af9ab66e753c643d73e64e0f9..4d44a1ce09950746640a3e7f5bf553fc7d3bbb30 100644 (file)
@@ -45,7 +45,9 @@ int ERR_load_CRYPTO_strings(void);
 # define CRYPTO_F_OPENSSL_SK_DUP                          128
 # define CRYPTO_F_OSSL_PROVIDER_ADD_BUILTIN               132
 # define CRYPTO_F_OSSL_PROVIDER_ACTIVATE                  130
+# define CRYPTO_F_OSSL_PROVIDER_ADD_PARAMETER             139
 # define CRYPTO_F_OSSL_PROVIDER_NEW                       131
+# define CRYPTO_F_OSSL_PROVIDER_SET_MODULE_PATH           140
 # define CRYPTO_F_PKEY_HMAC_INIT                          123
 # define CRYPTO_F_PKEY_POLY1305_INIT                      124
 # define CRYPTO_F_PKEY_SIPHASH_INIT                       125