Initial ENGINE config module, docs to follow.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 21 Jan 2002 03:02:36 +0000 (03:02 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 21 Jan 2002 03:02:36 +0000 (03:02 +0000)
Fix buffer overrun errors in OPENSSL_conf().

CHANGES
crypto/conf/conf.h
crypto/conf/conf_mall.c
crypto/conf/conf_mod.c
crypto/engine/Makefile.ssl
crypto/engine/eng_cnf.c [new file with mode: 0644]
crypto/engine/eng_err.c
crypto/engine/eng_list.c
crypto/engine/engine.h

diff --git a/CHANGES b/CHANGES
index db838b0509839d8e2b99247db6ad5eb032cb7bc2..a56411c12b4616353c9131b195143b7f4528314c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,9 @@
          *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7
          +) applies to 0.9.7 only
 
+  +) Prelminary ENGINE config module.
+     [Steve Henson]
+
   *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of
      ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag
      variable as an indication that a ClientHello message has been
index df84fa4de40483e7678ef99b9aab03f7e1dc4829..26452d4c81e55a51f8667a75d4975e95f4eb3836 100644 (file)
@@ -188,6 +188,8 @@ void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
 void *CONF_module_get_usr_data(CONF_MODULE *pmod);
 void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
 
+char *CONF_get1_default_config_file(void);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
index 3e752ac694b6aa4859862b25844dabf5f78231ce..814d5df8774c070fd73133935cfe2a4229d47400 100644 (file)
 #include <openssl/dso.h>
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
+#include <openssl/engine.h>
 
 void OPENSSL_load_builtin_modules(void)
        {
        /* Add builtin modules here */
        ASN1_add_oid_module();
+       ENGINE_add_conf_module();
        }
 
 /* This is the automatic configuration loader: it is called automatically by
@@ -77,32 +79,24 @@ void OPENSSL_load_builtin_modules(void)
 
 static int openssl_configured = 0;
 
-#if 0 /* Disabled because of obvious buffer overflow.
-       * This is not yet actually used anywhere -- but it shouldn't
-       * unless it is fixed first. */
 void OPENSSL_config(void)
        {
-       char *file, config_name[256];
+       int ret;
+       char *file;
        if (openssl_configured)
                return;
 
        OPENSSL_load_builtin_modules();
 
-       file = getenv("OPENSSL_CONF");
+       file = CONF_get1_default_config_file();
        if (!file)
-                {
-               strcpy(config_name,X509_get_default_cert_area());
-#ifndef OPENSSL_SYS_VMS
-               strcat(config_name,"/");
-#endif
-               strcat(config_name,OPENSSL_CONF);
-               file=config_name;
-                }
+               return;
 
-       if(CONF_modules_load_file(file, "openssl_config", 0) <= 0)
+       ret = CONF_modules_load_file(file, "openssl_config", 0);
+       OPENSSL_free(file);
+       if (ret <= 0)
                {
                BIO *bio_err;
-
                ERR_load_crypto_strings();
                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
                        {
@@ -116,7 +110,6 @@ void OPENSSL_config(void)
        return;
 
        }
-#endif
 
 void OPENSSL_no_config()
        {
index e2e357fe6adc1b32a053a1d684dbf2e84865b411..234eb7a06e52552594de7c056755f23848b45527 100644 (file)
@@ -520,3 +520,32 @@ void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
        pmod->usr_data = usr_data;
        }
 
+/* Return default config file name */
+
+char *CONF_get1_default_config_file(void)
+       {
+       char *file;
+       int len;
+
+       file = getenv("OPENSSL_CONF");
+       if (file) 
+               return BUF_strdup(file);
+
+       len = strlen(X509_get_default_cert_area());
+#ifndef OPENSSL_SYS_VMS
+       len++;
+#endif
+       len += strlen(OPENSSL_CONF);
+
+       file = OPENSSL_malloc(len + 1);
+
+       if (!file)
+               return NULL;
+       strcpy(file,X509_get_default_cert_area());
+#ifndef OPENSSL_SYS_VMS
+       strcat(file,"/");
+#endif
+       strcat(file,OPENSSL_CONF);
+
+       return file;
+       }
index de82b08355cd76286b47835c5b32c091eadacf18..4b0ae0552d649e8008a8e79b1f3024241c11408f 100644 (file)
@@ -26,13 +26,13 @@ LIB=$(TOP)/libcrypto.a
 LIBSRC= eng_err.c eng_lib.c eng_list.c eng_init.c eng_ctrl.c \
        eng_table.c eng_pkey.c eng_fat.c eng_all.c \
        tb_rsa.c tb_dsa.c tb_dh.c tb_rand.c tb_cipher.c tb_digest.c \
-       eng_openssl.c eng_dyn.c \
+       eng_openssl.c eng_dyn.c eng_cnf.c \
        hw_atalla.c hw_cswift.c hw_ncipher.c hw_nuron.c hw_ubsec.c \
        hw_openbsd_dev_crypto.c
 LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
        eng_table.o eng_pkey.o eng_fat.o eng_all.o \
        tb_rsa.o tb_dsa.o tb_dh.o tb_rand.o tb_cipher.o tb_digest.o \
-       eng_openssl.o eng_dyn.o \
+       eng_openssl.o eng_dyn.o eng_cnf.o \
        hw_atalla.o hw_cswift.o hw_ncipher.o hw_nuron.o hw_ubsec.o \
        hw_openbsd_dev_crypto.o
 
diff --git a/crypto/engine/eng_cnf.c b/crypto/engine/eng_cnf.c
new file mode 100644 (file)
index 0000000..8e3f894
--- /dev/null
@@ -0,0 +1,187 @@
+/* eng_cnf.c */
+/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+
+/* #define ENGINE_CONF_DEBUG */
+
+/* ENGINE config module */
+
+static char *skip_dot(char *name)
+       {
+       char *p;
+       p = strchr(name, '.');
+       if (p)
+               return p + 1;
+       return name;
+       }
+
+int int_engine_configure(char *name, char *value, const CONF *cnf)
+       {
+       int i;
+       int ret = 0;
+       STACK_OF(CONF_VALUE) *ecmds;
+       CONF_VALUE *ecmd;
+       char *ctrlname, *ctrlvalue;
+       ENGINE *e = NULL;
+       name = skip_dot(name);
+#ifdef ENGINE_CONF_DEBUG
+       fprintf(stderr, "Configuring engine %s\n", name);
+#endif
+       /* Value is a section containing ENGINE commands */
+       ecmds = NCONF_get_section(cnf, value);
+
+       if (!ecmds)
+               {
+               ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR);
+               return 0;
+               }
+
+       for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++)
+               {
+               ecmd = sk_CONF_VALUE_value(ecmds, i);
+               ctrlname = skip_dot(ecmd->name);
+               ctrlvalue = ecmd->value;
+#ifdef ENGINE_CONF_DEBUG
+       fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue);
+#endif
+
+               /* First handle some special pseudo ctrls */
+
+               /* Override engine name to use */
+               if (!strcmp(ctrlname, "engine_id"))
+                       name = ctrlvalue;
+               /* Load a dynamic ENGINE */
+               else if (!strcmp(ctrlname, "dynamic_path"))
+                       {
+                       e = ENGINE_by_id("dynamic");
+                       if (!e)
+                               goto err;
+                       if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
+                               goto err;
+                       if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+                               goto err;
+                       }
+               /* ... add other pseudos here ... */
+               else
+                       {
+                       /* At this point we need an ENGINE structural reference
+                        * if we don't already have one.
+                        */
+                       if (!e)
+                               {
+                               e = ENGINE_by_id(name);
+                               if (!e)
+                                       return 0;
+                               }
+                       /* Allow "EMPTY" to mean no value: this allows a valid
+                        * "value" to be passed to ctrls of type NO_INPUT
+                        */
+                       if (!strcmp(ctrlvalue, "EMPTY"))
+                               ctrlvalue = NULL;
+                       if (!ENGINE_ctrl_cmd_string(e,
+                                       ctrlname, ctrlvalue, 0))
+                               return 0;
+                       }
+
+
+               }
+       ret = 1;
+       err:
+       if (e)
+               ENGINE_free(e);
+       return ret;
+       }
+       
+
+static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
+       {
+       STACK_OF(CONF_VALUE) *elist;
+       CONF_VALUE *cval;
+       int i;
+#ifdef ENGINE_CONF_DEBUG
+       fprintf(stderr, "Called engine module: name %s, value %s\n",
+                       CONF_imodule_get_name(md), CONF_imodule_get_value(md));
+#endif
+       /* Value is a section containing ENGINEs to configure */
+       elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
+
+       if (!elist)
+               {
+               ENGINEerr(ENGINE_F_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR);
+               return 0;
+               }
+
+       for (i = 0; i < sk_CONF_VALUE_num(elist); i++)
+               {
+               cval = sk_CONF_VALUE_value(elist, i);
+               if (!int_engine_configure(cval->name, cval->value, cnf))
+                       return 0;
+               }
+
+       return 1;
+       }
+
+void ENGINE_add_conf_module(void)
+       {
+       CONF_module_add("engines", int_engine_module_init, 0);
+       }
index 2fe4c05d4516e449e39bf3e49340123ef600a817..f3c0c35863b62a3e1dcd3fedd5128332dad69eaf 100644 (file)
@@ -87,6 +87,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
 {ERR_PACK(0,ENGINE_F_ENGINE_LIST_REMOVE,0),    "ENGINE_LIST_REMOVE"},
 {ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,0),       "ENGINE_load_private_key"},
 {ERR_PACK(0,ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,0),        "ENGINE_load_public_key"},
+{ERR_PACK(0,ENGINE_F_ENGINE_MODULE_INIT,0),    "ENGINE_MODULE_INIT"},
 {ERR_PACK(0,ENGINE_F_ENGINE_NEW,0),    "ENGINE_new"},
 {ERR_PACK(0,ENGINE_F_ENGINE_REMOVE,0), "ENGINE_remove"},
 {ERR_PACK(0,ENGINE_F_ENGINE_SET_DEFAULT_TYPE,0),       "ENGINE_SET_DEFAULT_TYPE"},
@@ -95,6 +96,7 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
 {ERR_PACK(0,ENGINE_F_ENGINE_TABLE_REGISTER,0), "ENGINE_TABLE_REGISTER"},
 {ERR_PACK(0,ENGINE_F_ENGINE_UNLOAD_KEY,0),     "ENGINE_UNLOAD_KEY"},
 {ERR_PACK(0,ENGINE_F_INT_CTRL_HELPER,0),       "INT_CTRL_HELPER"},
+{ERR_PACK(0,ENGINE_F_INT_ENGINE_CONFIGURE,0),  "INT_ENGINE_CONFIGURE"},
 {ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0),   "LOG_MESSAGE"},
 {ERR_PACK(0,ENGINE_F_SET_DATA_CTX,0),  "SET_DATA_CTX"},
 {0,NULL}
@@ -118,7 +120,9 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
 {ENGINE_R_DSO_FAILURE                    ,"DSO failure"},
 {ENGINE_R_DSO_FUNCTION_NOT_FOUND         ,"dso function not found"},
 {ENGINE_R_DSO_NOT_FOUND                  ,"dso not found"},
+{ENGINE_R_ENGINES_SECTION_ERROR          ,"engines section error"},
 {ENGINE_R_ENGINE_IS_NOT_IN_LIST          ,"engine is not in the list"},
+{ENGINE_R_ENGINE_SECTION_ERROR           ,"engine section error"},
 {ENGINE_R_FAILED_LOADING_PRIVATE_KEY     ,"failed loading private key"},
 {ENGINE_R_FAILED_LOADING_PUBLIC_KEY      ,"failed loading public key"},
 {ENGINE_R_FINISH_FAILED                  ,"finish failed"},
index c76e6ad8973f4d9f62704c96a70915c559c9ea5b..0c220558e78592e741e6323e669ce5783c036892 100644 (file)
@@ -374,7 +374,10 @@ ENGINE *ENGINE_by_id(const char *id)
                }
        CRYPTO_r_unlock(CRYPTO_LOCK_ENGINE);
        if(iterator == NULL)
+               {
                ENGINEerr(ENGINE_F_ENGINE_BY_ID,
                        ENGINE_R_NO_SUCH_ENGINE);
+               ERR_add_error_data(2, "id=", id);
+               }
        return iterator;
        }
index 782d85a9be8f0e6364a691ed51e8f6096d739562..291841abcc66981ac27f10acd571f0655a28f71c 100644 (file)
@@ -517,6 +517,8 @@ int ENGINE_set_default_digests(ENGINE *e);
  * selective functions. */
 int ENGINE_set_default(ENGINE *e, unsigned int flags);
 
+void ENGINE_add_conf_module(void);
+
 /* Deprecated functions ... */
 /* int ENGINE_clear_defaults(void); */
 
@@ -622,7 +624,6 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
  * made after this point may be overwritten when the script is next run.
  */
 void ERR_load_ENGINE_strings(void);
-
 /* Error codes for the ENGINE functions. */
 
 /* Function codes. */
@@ -647,6 +648,7 @@ void ERR_load_ENGINE_strings(void);
 #define ENGINE_F_ENGINE_LIST_REMOVE                     121
 #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY                150
 #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY                         151
+#define ENGINE_F_ENGINE_MODULE_INIT                     187
 #define ENGINE_F_ENGINE_NEW                             122
 #define ENGINE_F_ENGINE_REMOVE                          123
 #define ENGINE_F_ENGINE_SET_DEFAULT_TYPE                126
@@ -655,6 +657,7 @@ void ERR_load_ENGINE_strings(void);
 #define ENGINE_F_ENGINE_TABLE_REGISTER                  184
 #define ENGINE_F_ENGINE_UNLOAD_KEY                      152
 #define ENGINE_F_INT_CTRL_HELPER                        172
+#define ENGINE_F_INT_ENGINE_CONFIGURE                   188
 #define ENGINE_F_LOG_MESSAGE                            141
 #define ENGINE_F_SET_DATA_CTX                           183
 
@@ -675,7 +678,9 @@ void ERR_load_ENGINE_strings(void);
 #define ENGINE_R_DSO_FAILURE                            104
 #define ENGINE_R_DSO_FUNCTION_NOT_FOUND                         131
 #define ENGINE_R_DSO_NOT_FOUND                          132
+#define ENGINE_R_ENGINES_SECTION_ERROR                  148
 #define ENGINE_R_ENGINE_IS_NOT_IN_LIST                  105
+#define ENGINE_R_ENGINE_SECTION_ERROR                   149
 #define ENGINE_R_FAILED_LOADING_PRIVATE_KEY             128
 #define ENGINE_R_FAILED_LOADING_PUBLIC_KEY              129
 #define ENGINE_R_FINISH_FAILED                          106