tolerate broken CMS/PKCS7 implementations using signature OID instead of digest
[oweals/openssl.git] / crypto / engine / eng_cnf.c
index 8e3f894f66e56cde7002ed722964216c1c136d47..08066cea592cad9a0970221e8ee21eb26034a985 100644 (file)
@@ -1,5 +1,5 @@
 /* eng_cnf.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
  *
  */
 
-#include <stdio.h>
-#include <openssl/crypto.h>
-#include "cryptlib.h"
+#include "eng_int.h"
 #include <openssl/conf.h>
-#include <openssl/engine.h>
 
 /* #define ENGINE_CONF_DEBUG */
 
@@ -75,14 +72,34 @@ static char *skip_dot(char *name)
        return name;
        }
 
-int int_engine_configure(char *name, char *value, const CONF *cnf)
+static STACK_OF(ENGINE) *initialized_engines = NULL;
+
+static int int_engine_init(ENGINE *e)
+       {
+       if (!ENGINE_init(e))
+               return 0;
+       if (!initialized_engines)
+               initialized_engines = sk_ENGINE_new_null();
+       if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e))
+               {
+               ENGINE_finish(e);
+               return 0;
+               }
+       return 1;
+       }
+       
+
+static int int_engine_configure(char *name, char *value, const CONF *cnf)
        {
        int i;
        int ret = 0;
+       long do_init = -1;
        STACK_OF(CONF_VALUE) *ecmds;
        CONF_VALUE *ecmd;
        char *ctrlname, *ctrlvalue;
        ENGINE *e = NULL;
+       int soft = 0;
+
        name = skip_dot(name);
 #ifdef ENGINE_CONF_DEBUG
        fprintf(stderr, "Configuring engine %s\n", name);
@@ -110,6 +127,8 @@ int int_engine_configure(char *name, char *value, const CONF *cnf)
                /* Override engine name to use */
                if (!strcmp(ctrlname, "engine_id"))
                        name = ctrlvalue;
+               else if (!strcmp(ctrlname, "soft_load"))
+                       soft = 1;
                /* Load a dynamic ENGINE */
                else if (!strcmp(ctrlname, "dynamic_path"))
                        {
@@ -118,6 +137,8 @@ int int_engine_configure(char *name, char *value, const CONF *cnf)
                                goto err;
                        if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
                                goto err;
+                       if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
+                               goto err;
                        if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
                                goto err;
                        }
@@ -130,6 +151,11 @@ int int_engine_configure(char *name, char *value, const CONF *cnf)
                        if (!e)
                                {
                                e = ENGINE_by_id(name);
+                               if (!e && soft)
+                                       {
+                                       ERR_clear_error();
+                                       return 1;
+                                       }
                                if (!e)
                                        return 0;
                                }
@@ -138,20 +164,43 @@ int int_engine_configure(char *name, char *value, const CONF *cnf)
                         */
                        if (!strcmp(ctrlvalue, "EMPTY"))
                                ctrlvalue = NULL;
-                       if (!ENGINE_ctrl_cmd_string(e,
+                       if (!strcmp(ctrlname, "init"))
+                               {
+                               if (!NCONF_get_number_e(cnf, value, "init", &do_init))
+                                       goto err;
+                               if (do_init == 1)
+                                       {
+                                       if (!int_engine_init(e))
+                                               goto err;
+                                       }
+                               else if (do_init != 0)
+                                       {
+                                       ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE);
+                                       goto err;
+                                       }
+                               }
+                       else if (!strcmp(ctrlname, "default_algorithms"))
+                               {
+                               if (!ENGINE_set_default_string(e, ctrlvalue))
+                                       goto err;
+                               }
+                       else if (!ENGINE_ctrl_cmd_string(e,
                                        ctrlname, ctrlvalue, 0))
                                return 0;
                        }
 
 
+
                }
+       if (e && (do_init == -1) && !int_engine_init(e))
+               goto err;
        ret = 1;
        err:
        if (e)
                ENGINE_free(e);
        return ret;
        }
-       
+
 
 static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
        {
@@ -167,7 +216,7 @@ static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
 
        if (!elist)
                {
-               ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
+               ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
                return 0;
                }
 
@@ -181,7 +230,19 @@ static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
        return 1;
        }
 
+static void int_engine_module_finish(CONF_IMODULE *md)
+       {
+       ENGINE *e;
+       while ((e = sk_ENGINE_pop(initialized_engines)))
+               ENGINE_finish(e);
+       sk_ENGINE_free(initialized_engines);
+       initialized_engines = NULL;
+       }
+       
+
 void ENGINE_add_conf_module(void)
        {
-       CONF_module_add("engines", int_engine_module_init, 0);
+       CONF_module_add("engines",
+                       int_engine_module_init,
+                       int_engine_module_finish);
        }