Add support for passing the libctx to the config loader
[openssl.git] / crypto / conf / conf_mod.c
index 4ce3951ddc3583617eeac409e918a89a96b5159f..2bbf43b90829ba8d9eb604c533775d67924776e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2020 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 <openssl/crypto.h>
 #include "internal/conf.h"
 #include "internal/dso.h"
+#include "internal/thread_once.h"
 #include <openssl/x509.h>
+#include <openssl/trace.h>
+#include <openssl/engine.h>
 
 #define DSO_mod_init_name "OPENSSL_init"
 #define DSO_mod_finish_name "OPENSSL_finish"
@@ -54,6 +57,8 @@ struct conf_imodule_st {
 static STACK_OF(CONF_MODULE) *supported_modules = NULL;
 static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
 
+static CRYPTO_ONCE load_builtin_modules = CRYPTO_ONCE_STATIC_INIT;
+
 static void module_free(CONF_MODULE *md);
 static void module_finish(CONF_IMODULE *imod);
 static int module_run(const CONF *cnf, const char *name, const char *value,
@@ -92,6 +97,7 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
         return 1;
     }
 
+    OSSL_TRACE1(CONF, "Configuration in section %s\n", vsection);
     values = NCONF_get_section(cnf, vsection);
 
     if (!values)
@@ -100,6 +106,8 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
     for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
         vl = sk_CONF_VALUE_value(values, i);
         ret = module_run(cnf, vl->name, vl->value, flags);
+        OSSL_TRACE3(CONF, "Running module %s (%s) returned %d\n",
+                    vl->name, vl->value, ret);
         if (ret <= 0)
             if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
                 return ret;
@@ -109,22 +117,25 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
 
 }
 
-int CONF_modules_load_file(const char *filename, const char *appname,
-                           unsigned long flags)
+int CONF_modules_load_file_with_libctx(OPENSSL_CTX *libctx,
+                                       const char *filename,
+                                       const char *appname, unsigned long flags)
 {
     char *file = NULL;
     CONF *conf = NULL;
     int ret = 0;
-    conf = NCONF_new(NULL);
+
+    conf = NCONF_new_with_libctx(libctx, NULL);
     if (conf == NULL)
         goto err;
 
     if (filename == NULL) {
         file = CONF_get1_default_config_file();
-        if (!file)
+        if (file == NULL)
             goto err;
-    } else
+    } else {
         file = (char *)filename;
+    }
 
     if (NCONF_load(conf, file, NULL) <= 0) {
         if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
@@ -142,15 +153,38 @@ int CONF_modules_load_file(const char *filename, const char *appname,
         OPENSSL_free(file);
     NCONF_free(conf);
 
+    if (flags & CONF_MFLAGS_IGNORE_RETURN_CODES)
+        return 1;
+
     return ret;
 }
 
+int CONF_modules_load_file(const char *filename,
+                           const char *appname, unsigned long flags)
+{
+    return CONF_modules_load_file_with_libctx(NULL, filename, appname, flags);
+}
+
+DEFINE_RUN_ONCE_STATIC(do_load_builtin_modules)
+{
+    OPENSSL_load_builtin_modules();
+#ifndef OPENSSL_NO_ENGINE
+    /* Need to load ENGINEs */
+    ENGINE_load_builtin_engines();
+#endif
+    ERR_clear_error();
+    return 1;
+}
+
 static int module_run(const CONF *cnf, const char *name, const char *value,
                       unsigned long flags)
 {
     CONF_MODULE *md;
     int ret;
 
+    if (!RUN_ONCE(&load_builtin_modules, do_load_builtin_modules))
+        return -1;
+
     md = module_find(name);
 
     /* Module not found: try to load DSO */
@@ -191,19 +225,20 @@ static CONF_MODULE *module_load_dso(const CONF *cnf,
     const char *path = NULL;
     int errcode = 0;
     CONF_MODULE *md;
+
     /* Look for alternative path in module section */
     path = NCONF_get_string(cnf, value, "path");
-    if (!path) {
+    if (path == NULL) {
         ERR_clear_error();
         path = name;
     }
     dso = DSO_load(NULL, path, NULL, 0);
-    if (!dso) {
+    if (dso == NULL) {
         errcode = CONF_R_ERROR_LOADING_DSO;
         goto err;
     }
     ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
-    if (!ifunc) {
+    if (ifunc == NULL) {
         errcode = CONF_R_MISSING_INIT_FUNCTION;
         goto err;
     }
@@ -211,7 +246,7 @@ static CONF_MODULE *module_load_dso(const CONF *cnf,
     /* All OK, add module */
     md = module_add(dso, name, ifunc, ffunc);
 
-    if (!md)
+    if (md == NULL)
         goto err;
 
     return md;
@@ -526,7 +561,7 @@ int CONF_parse_list(const char *list_, int sep, int nospc,
                 lstart++;
         }
         p = strchr(lstart, sep);
-        if (p == lstart || !*lstart)
+        if (p == lstart || *lstart == '\0')
             ret = list_cb(NULL, 0, arg);
         else {
             if (p)