update to 9.7.1-P2
[tridge/bind9.git] / lib / dns / openssl_link.c
index 2dc7d7e4880762f0954162cb5465b56b194536fc..04999b0b5ca193da8e2182f2c21061a9f25886c8 100644 (file)
@@ -31,7 +31,7 @@
 
 /*
  * Principal Author: Brian Wellington
- * $Id: openssl_link.c,v 1.22.112.3 2009/02/11 03:07:01 jinmei Exp $
+ * $Id: openssl_link.c,v 1.27 2009/10/05 17:30:49 fdupont Exp $
  */
 #ifdef OPENSSL
 
@@ -45,6 +45,8 @@
 #include <isc/thread.h>
 #include <isc/util.h>
 
+#include <dst/result.h>
+
 #include "dst_internal.h"
 #include "dst_openssl.h"
 
 
 #ifdef USE_ENGINE
 #include <openssl/engine.h>
-
-#ifdef ENGINE_ID
-const char *engine_id = ENGINE_ID;
-#else
-const char *engine_id;
-#endif
 #endif
 
 static RAND_METHOD *rm = NULL;
@@ -74,15 +70,7 @@ static isc_mutex_t *locks = NULL;
 static int nlocks;
 
 #ifdef USE_ENGINE
-static ENGINE *e;
-static ENGINE *he;
-#endif
-
-#ifdef USE_PKCS11
-static isc_result_t
-dst__openssl_load_engine(const char *name, const char *engine_id,
-                        const char **pre_cmds, int pre_num,
-                        const char **post_cmds, int post_num);
+static ENGINE *e = NULL;
 #endif
 
 static int
@@ -135,8 +123,16 @@ id_callback(void) {
 
 static void *
 mem_alloc(size_t size) {
+#ifdef OPENSSL_LEAKS
+       void *ptr;
+
+       INSIST(dst__memory_pool != NULL);
+       ptr = isc_mem_allocate(dst__memory_pool, size);
+       return (ptr);
+#else
        INSIST(dst__memory_pool != NULL);
        return (isc_mem_allocate(dst__memory_pool, size));
+#endif
 }
 
 static void
@@ -148,16 +144,26 @@ mem_free(void *ptr) {
 
 static void *
 mem_realloc(void *ptr, size_t size) {
+#ifdef OPENSSL_LEAKS
+       void *rptr;
+
+       INSIST(dst__memory_pool != NULL);
+       rptr = isc_mem_reallocate(dst__memory_pool, ptr, size);
+       return (rptr);
+#else
        INSIST(dst__memory_pool != NULL);
        return (isc_mem_reallocate(dst__memory_pool, ptr, size));
+#endif
 }
 
 isc_result_t
-dst__openssl_init() {
+dst__openssl_init(const char *engine) {
        isc_result_t result;
 #ifdef USE_ENGINE
-       /* const char  *name; */
        ENGINE *re;
+#else
+
+       UNUSED(engine);
 #endif
 
 #ifdef  DNS_CRYPTO_LEAKS
@@ -187,70 +193,26 @@ dst__openssl_init() {
        rm->add = entropy_add;
        rm->pseudorand = entropy_getpseudo;
        rm->status = entropy_status;
+
 #ifdef USE_ENGINE
        OPENSSL_config(NULL);
-#ifdef USE_PKCS11
-#ifndef PKCS11_SO_PATH
-#define PKCS11_SO_PATH         "/usr/local/lib/engines/engine_pkcs11.so"
-#endif
-#ifndef PKCS11_MODULE_PATH
-#define PKCS11_MODULE_PATH     "/usr/lib/libpkcs11.so"
-#endif
-       {
-               /*
-                * to use this to config the PIN, add in openssl.cnf:
-                *  - at the beginning: "openssl_conf = openssl_def"
-                *  - at any place these sections:
-                * [ openssl_def ]
-                * engines = engine_section
-                * [ engine_section ]
-                * pkcs11 = pkcs11_section
-                * [ pkcs11_section ]
-                * PIN = my___pin
-                */
-
-               const char *pre_cmds[] = {
-                       "SO_PATH", PKCS11_SO_PATH,
-                       "LOAD", NULL,
-                       "MODULE_PATH", PKCS11_MODULE_PATH
-               };
-               const char *post_cmds[] = {
-                       /* "PIN", "my___pin" */
-               };
-               result = dst__openssl_load_engine("pkcs11", "pkcs11",
-                                                 pre_cmds, 0,
-                                                 post_cmds, /*1*/ 0);
-               if (result != ISC_R_SUCCESS)
-                       goto cleanup_rm;
-       }
-#endif /* USE_PKCS11 */
-       if (engine_id != NULL) {
-               e = ENGINE_by_id(engine_id);
+
+       if (engine != NULL && *engine == '\0')
+               engine = NULL;
+
+       if (engine != NULL) {
+               e = ENGINE_by_id(engine);
                if (e == NULL) {
-                       result = ISC_R_NOTFOUND;
+                       result = DST_R_NOENGINE;
                        goto cleanup_rm;
                }
-               if (!ENGINE_init(e)) {
-                       result = ISC_R_FAILURE;
-                       ENGINE_free(e);
+               /* This will init the engine. */
+               if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+                       result = DST_R_NOENGINE;
                        goto cleanup_rm;
                }
-               ENGINE_set_default(e, ENGINE_METHOD_ALL);
-               ENGINE_free(e);
-       } else {
-               ENGINE_register_all_complete();
-               for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
-
-                       /*
-                        * Something weird here. If we call ENGINE_finish()
-                        * ENGINE_get_default_RAND() will fail.
-                        */
-                       if (ENGINE_init(e)) {
-                               if (he == NULL)
-                                       he = e;
-                       }
-               }
        }
+
        re = ENGINE_get_default_RAND();
        if (re == NULL) {
                re = ENGINE_new();
@@ -263,7 +225,6 @@ dst__openssl_init() {
                ENGINE_free(re);
        } else
                ENGINE_finish(re);
-
 #else
        RAND_set_rand_method(rm);
 #endif /* USE_ENGINE */
@@ -271,13 +232,18 @@ dst__openssl_init() {
 
 #ifdef USE_ENGINE
  cleanup_rm:
+       if (e != NULL)
+               ENGINE_free(e);
+       e = NULL;
        mem_free(rm);
+       rm = NULL;
 #endif
  cleanup_mutexinit:
        CRYPTO_set_locking_callback(NULL);
        DESTROYMUTEXBLOCK(locks, nlocks);
  cleanup_mutexalloc:
        mem_free(locks);
+       locks = NULL;
        return (result);
 }
 
@@ -287,15 +253,22 @@ dst__openssl_destroy() {
        /*
         * Sequence taken from apps_shutdown() in <apps/apps.h>.
         */
+       if (rm != NULL) {
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+               RAND_cleanup();
+#endif
+               mem_free(rm);
+               rm = NULL;
+       }
 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-       CONF_modules_unload(1);
+       CONF_modules_free();
 #endif
+       OBJ_cleanup();
        EVP_cleanup();
 #if defined(USE_ENGINE)
-       if (e != NULL) {
-               ENGINE_finish(e);
-               e = NULL;
-       }
+       if (e != NULL)
+               ENGINE_free(e);
+       e = NULL;
 #if defined(USE_ENGINE) && OPENSSL_VERSION_NUMBER >= 0x00907000L
        ENGINE_cleanup();
 #endif
@@ -304,23 +277,18 @@ dst__openssl_destroy() {
        CRYPTO_cleanup_all_ex_data();
 #endif
        ERR_clear_error();
-       ERR_free_strings();
        ERR_remove_state(0);
+       ERR_free_strings();
 
 #ifdef  DNS_CRYPTO_LEAKS
        CRYPTO_mem_leaks_fp(stderr);
 #endif
 
-       if (rm != NULL) {
-#if OPENSSL_VERSION_NUMBER >= 0x00907000L
-               RAND_cleanup();
-#endif
-               mem_free(rm);
-       }
        if (locks != NULL) {
                CRYPTO_set_locking_callback(NULL);
                DESTROYMUTEXBLOCK(locks, nlocks);
                mem_free(locks);
+               locks = NULL;
        }
 }
 
@@ -341,91 +309,18 @@ dst__openssl_toresult(isc_result_t fallback) {
 }
 
 ENGINE *
-dst__openssl_getengine(const char *name) {
-
-       UNUSED(name);
-
+dst__openssl_getengine(const char *engine) {
 
+       if (engine == NULL)
+               return (NULL);
 #if defined(USE_ENGINE)
-       return (he);
-#else
-       return (NULL);
-#endif
-}
-
-isc_result_t
-dst__openssl_setdefault(const char *name) {
-
-       UNUSED(name);
-
-#if defined(USE_ENGINE)
-       ENGINE_set_default(e, ENGINE_METHOD_ALL);
-#endif
-       /*
-        * XXXMPA If the engine does not have a default RAND method
-        * restore our method.
-        */
-       return (ISC_R_SUCCESS);
-}
-
-#ifdef USE_PKCS11
-/*
- * 'name' is the name the engine is known by to the dst library.
- * This may or may not match the name the engine is known by to
- * openssl.  It is the name that is stored in the private key file.
- *
- * 'engine_id' is the openssl engine name.
- *
- * pre_cmds and post_cmds a sequence if command argument pairs
- * pre_num and post_num are a count of those pairs.
- *
- * "SO_PATH", PKCS11_SO_PATH ("/usr/local/lib/engines/engine_pkcs11.so")
- * "LOAD", NULL
- * "MODULE_PATH", PKCS11_MODULE_PATH ("/usr/lib/libpkcs11.so")
- */
-static isc_result_t
-dst__openssl_load_engine(const char *name, const char *engine_id,
-                        const char **pre_cmds, int pre_num,
-                        const char **post_cmds, int post_num)
-{
-       ENGINE *e;
-
-       UNUSED(name);
-
-       if (!strcasecmp(engine_id, "dynamic"))
-               ENGINE_load_dynamic();
-       e = ENGINE_by_id(engine_id);
        if (e == NULL)
-               return (ISC_R_NOTFOUND);
-       while (pre_num--) {
-               if (!ENGINE_ctrl_cmd_string(e, pre_cmds[0], pre_cmds[1], 0)) {
-                       ENGINE_free(e);
-                       return (ISC_R_FAILURE);
-               }
-               pre_cmds += 2;
-       }
-       if (!ENGINE_init(e)) {
-               ENGINE_free(e);
-               return (ISC_R_FAILURE);
-       }
-       /*
-        * ENGINE_init() returned a functional reference, so free the
-        * structural reference from ENGINE_by_id().
-        */
-       ENGINE_free(e);
-       while (post_num--) {
-               if (!ENGINE_ctrl_cmd_string(e, post_cmds[0], post_cmds[1], 0)) {
-                       ENGINE_free(e);
-                       return (ISC_R_FAILURE);
-               }
-               post_cmds += 2;
-       }
-       if (he != NULL)
-               ENGINE_finish(he);
-       he = e;
-       return (ISC_R_SUCCESS);
+               return (NULL);
+       if (strcmp(engine, ENGINE_get_id(e)) == 0)
+               return (e);
+#endif
+       return (NULL);
 }
-#endif /* USE_PKCS11 */
 
 #else /* OPENSSL */