Some more tweaks to ENGINE code.
authorGeoff Thorpe <geoff@openssl.org>
Wed, 18 Apr 2001 21:46:00 +0000 (21:46 +0000)
committerGeoff Thorpe <geoff@openssl.org>
Wed, 18 Apr 2001 21:46:00 +0000 (21:46 +0000)
The existing ENGINEs (including the default 'openssl' software engine) were
static, declared inside the source file for each engine implementation. The
reason this was not going boom was that all the ENGINEs had reference
counts that never hit zero (once linked into the internal list, each would
always have at least 1 lasting structural reference).

To fix this so it will stay standing when an "unload" function is added to
match ENGINE_load_builtin_engines(), the "constructor" functions for each
ENGINE implementation have been changed to dynamically allocate and
construct their own ENGINEs using API functions. The other benefit of this
is that no ENGINE implementation has to include the internal "engine_int.h"
header file any more.

crypto/engine/Makefile.ssl
crypto/engine/engine_openssl.c
crypto/engine/hw_atalla.c
crypto/engine/hw_cswift.c
crypto/engine/hw_ncipher.c
crypto/engine/hw_nuron.c
crypto/engine/hw_ubsec.c

index 1a548dea7c4ff4047dde288cc01dac78380fad7e..507821e37493836f476c43ba3680be0dc31bfb03 100644 (file)
@@ -182,7 +182,7 @@ engine_openssl.o: ../../include/openssl/rijndael.h
 engine_openssl.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
 engine_openssl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 engine_openssl.o: ../../include/openssl/stack.h
-engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
+engine_openssl.o: ../../include/openssl/symhacks.h ../cryptlib.h
 engine_openssl.o: engine_openssl.c
 hw_atalla.o: ../../e_os.h ../../include/openssl/asn1.h
 hw_atalla.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
@@ -203,8 +203,8 @@ hw_atalla.o: ../../include/openssl/rc5.h ../../include/openssl/rd_fst.h
 hw_atalla.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
 hw_atalla.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 hw_atalla.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
-hw_atalla.o: hw_atalla.c vendor_defns/atalla.h
+hw_atalla.o: ../../include/openssl/symhacks.h ../cryptlib.h hw_atalla.c
+hw_atalla.o: vendor_defns/atalla.h
 hw_cswift.o: ../../e_os.h ../../include/openssl/asn1.h
 hw_cswift.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
 hw_cswift.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -224,8 +224,8 @@ hw_cswift.o: ../../include/openssl/rc5.h ../../include/openssl/rd_fst.h
 hw_cswift.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
 hw_cswift.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 hw_cswift.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
-hw_cswift.o: hw_cswift.c vendor_defns/cswift.h
+hw_cswift.o: ../../include/openssl/symhacks.h ../cryptlib.h hw_cswift.c
+hw_cswift.o: vendor_defns/cswift.h
 hw_ncipher.o: ../../e_os.h ../../include/openssl/asn1.h
 hw_ncipher.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
 hw_ncipher.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -248,8 +248,7 @@ hw_ncipher.o: ../../include/openssl/ripemd.h ../../include/openssl/rsa.h
 hw_ncipher.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 hw_ncipher.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 hw_ncipher.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-hw_ncipher.o: ../cryptlib.h engine_int.h hw_ncipher.c
-hw_ncipher.o: vendor_defns/hwcryptohook.h
+hw_ncipher.o: ../cryptlib.h hw_ncipher.c vendor_defns/hwcryptohook.h
 hw_nuron.o: ../../e_os.h ../../include/openssl/asn1.h
 hw_nuron.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
 hw_nuron.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -269,8 +268,7 @@ hw_nuron.o: ../../include/openssl/rc5.h ../../include/openssl/rd_fst.h
 hw_nuron.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
 hw_nuron.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 hw_nuron.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-hw_nuron.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
-hw_nuron.o: hw_nuron.c
+hw_nuron.o: ../../include/openssl/symhacks.h ../cryptlib.h hw_nuron.c
 hw_ubsec.o: ../../e_os.h ../../include/openssl/asn1.h
 hw_ubsec.o: ../../include/openssl/bio.h ../../include/openssl/blowfish.h
 hw_ubsec.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -290,5 +288,5 @@ hw_ubsec.o: ../../include/openssl/rc5.h ../../include/openssl/rd_fst.h
 hw_ubsec.o: ../../include/openssl/rijndael.h ../../include/openssl/ripemd.h
 hw_ubsec.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 hw_ubsec.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-hw_ubsec.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h
-hw_ubsec.o: hw_ubsec.c vendor_defns/hw_ubsec.h
+hw_ubsec.o: ../../include/openssl/symhacks.h ../cryptlib.h hw_ubsec.c
+hw_ubsec.o: vendor_defns/hw_ubsec.h
index b8d90757843de01bf307ec0702037a2a436b8376..35cfd2354a3328cef567ced64b860c4e0880f841 100644 (file)
@@ -60,7 +60,6 @@
 #include <stdio.h>
 #include <openssl/crypto.h>
 #include "cryptlib.h"
-#include "engine_int.h"
 #include <openssl/engine.h>
 #include <openssl/dso.h>
 #include <openssl/rsa.h>
@@ -76,39 +75,30 @@ static int openssl_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
                const BIGNUM *q, const BIGNUM *dmp1, const BIGNUM *dmq1,
                const BIGNUM *iqmp, BN_CTX *ctx);
 
-/* The ENGINE structure that can be pointed to. */
-static ENGINE engine_openssl =
-        {
-       "openssl",
-       "Software default engine support",
-       NULL,
-       NULL,
-       NULL, /* these methods are "stolen" in ENGINE_openssl() */
-       NULL,
-       NULL,
-       openssl_mod_exp_crt,
-       NULL, /* no init() */
-       NULL, /* no finish() */
-       NULL, /* no ctrl() */
-       NULL, /* no load_privkey() */
-       NULL, /* no load_pubkey() */
-       0, /* no flags */
-       0, 0, /* no references. */
-       NULL, NULL /* unlinked */
-        };
+/* The constants used when creating the ENGINE */
+static const char *engine_openssl_id = "openssl";
+static const char *engine_openssl_name = "Software default engine support";
 
 /* As this is only ever called once, there's no need for locking
  * (indeed - the lock will already be held by our caller!!!) */
 ENGINE *ENGINE_openssl()
        {
-       /* We need to populate our structure with the software pointers
-        * that we want to steal. */
-       engine_openssl.rsa_meth = RSA_get_default_openssl_method();
-       engine_openssl.dsa_meth = DSA_get_default_openssl_method();
-       engine_openssl.dh_meth = DH_get_default_openssl_method();
-       engine_openssl.rand_meth = RAND_SSLeay();
-       engine_openssl.bn_mod_exp = BN_mod_exp;
-       return &engine_openssl;
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_openssl_id) ||
+                       !ENGINE_set_name(ret, engine_openssl_name) ||
+                       !ENGINE_set_RSA(ret, RSA_get_default_openssl_method()) ||
+                       !ENGINE_set_DSA(ret, DSA_get_default_openssl_method()) ||
+                       !ENGINE_set_DH(ret, DH_get_default_openssl_method()) ||
+                       !ENGINE_set_RAND(ret, RAND_SSLeay()) ||
+                       !ENGINE_set_BN_mod_exp(ret, BN_mod_exp) ||
+                       !ENGINE_set_BN_mod_exp_crt(ret, openssl_mod_exp_crt))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
+       return ret;
        }
 
 /* Chinese Remainder Theorem, taken and adapted from rsa_eay.c */
@@ -134,11 +124,11 @@ static int openssl_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        if (!BN_copy(temp_bn, iqmp)) goto err;
  
        if (!BN_mod(&r1, a, q, bn_ctx)) goto err;
-       if (!engine_openssl.bn_mod_exp(&m1, &r1, dmq1, q, bn_ctx))
+       if (!BN_mod_exp(&m1, &r1, dmq1, q, bn_ctx))
                goto err;
  
        if (!BN_mod(&r1, a, p, bn_ctx)) goto err;
-       if (!engine_openssl.bn_mod_exp(r, &r1, dmp1, p, bn_ctx))
+       if (!BN_mod_exp(r, &r1, dmp1, p, bn_ctx))
                goto err;
 
        if (!BN_sub(r, r, &m1)) goto err;
index acb432109f44dc34f088699c274c0065de5b7ca5..e3407e73c7fccc55895c8a7043fe6eb62366e4f0 100644 (file)
@@ -60,7 +60,6 @@
 #include <openssl/crypto.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
-#include "engine_int.h"
 #include <openssl/engine.h>
 
 #ifndef OPENSSL_NO_HW
@@ -146,26 +145,9 @@ static DH_METHOD atalla_dh =
        NULL
        };
 
-/* Our ENGINE structure. */
-static ENGINE engine_atalla =
-        {
-       "atalla",
-       "Atalla hardware engine support",
-       &atalla_rsa,
-       &atalla_dsa,
-       &atalla_dh,
-       NULL,
-       atalla_mod_exp,
-       NULL,
-       atalla_init,
-       atalla_finish,
-       NULL, /* no ctrl() */
-       NULL, /* no load_privkey() */
-       NULL, /* no load_pubkey() */
-       0, /* no flags */
-       0, 0, /* no references */
-       NULL, NULL /* unlinked */
-        };
+/* Constants used when creating the ENGINE */
+static const char *engine_atalla_id = "atalla";
+static const char *engine_atalla_name = "Atalla hardware engine support";
 
 /* As this is only ever called once, there's no need for locking
  * (indeed - the lock will already be held by our caller!!!) */
@@ -174,6 +156,21 @@ ENGINE *ENGINE_atalla()
        const RSA_METHOD *meth1;
        const DSA_METHOD *meth2;
        const DH_METHOD *meth3;
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_atalla_id) ||
+                       !ENGINE_set_name(ret, engine_atalla_name) ||
+                       !ENGINE_set_RSA(ret, &atalla_rsa) ||
+                       !ENGINE_set_DSA(ret, &atalla_dsa) ||
+                       !ENGINE_set_DH(ret, &atalla_dh) ||
+                       !ENGINE_set_BN_mod_exp(ret, atalla_mod_exp) ||
+                       !ENGINE_set_init_function(ret, atalla_init) ||
+                       !ENGINE_set_finish_function(ret, atalla_finish))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
 
        /* We know that the "PKCS1_SSLeay()" functions hook properly
         * to the atalla-specific mod_exp and mod_exp_crt so we use
@@ -199,7 +196,7 @@ ENGINE *ENGINE_atalla()
        meth3 = DH_OpenSSL();
        atalla_dh.generate_key = meth3->generate_key;
        atalla_dh.compute_key = meth3->compute_key;
-       return &engine_atalla;
+       return ret;
        }
 
 /* This is a process-global DSO handle used for loading and unloading
index 4066d1d164011e9fb75526dd577cf34194e45b5f..e9f62f61d3a9a37ec603af5e20a68733c8864b77 100644 (file)
@@ -60,7 +60,6 @@
 #include <openssl/crypto.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
-#include "engine_int.h"
 #include <openssl/engine.h>
 
 #ifndef OPENSSL_NO_HW
@@ -158,26 +157,9 @@ static DH_METHOD cswift_dh =
        NULL
        };
 
-/* Our ENGINE structure. */
-static ENGINE engine_cswift =
-        {
-       "cswift",
-       "CryptoSwift hardware engine support",
-       &cswift_rsa,
-       &cswift_dsa,
-       &cswift_dh,
-       NULL,
-       cswift_mod_exp,
-       cswift_mod_exp_crt,
-       cswift_init,
-       cswift_finish,
-       NULL, /* no ctrl() */
-       NULL, /* no load_privkey() */
-       NULL, /* no load_pubkey() */
-       0, /* no flags */
-       0, 0, /* no references */
-       NULL, NULL /* unlinked */
-        };
+/* Constants used when creating the ENGINE */
+static const char *engine_cswift_id = "cswift";
+static const char *engine_cswift_name = "CryptoSwift hardware engine support";
 
 /* As this is only ever called once, there's no need for locking
  * (indeed - the lock will already be held by our caller!!!) */
@@ -185,6 +167,22 @@ ENGINE *ENGINE_cswift()
        {
        const RSA_METHOD *meth1;
        const DH_METHOD *meth2;
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_cswift_id) ||
+                       !ENGINE_set_name(ret, engine_cswift_name) ||
+                       !ENGINE_set_RSA(ret, &cswift_rsa) ||
+                       !ENGINE_set_DSA(ret, &cswift_dsa) ||
+                       !ENGINE_set_DH(ret, &cswift_dh) ||
+                       !ENGINE_set_BN_mod_exp(ret, &cswift_mod_exp) ||
+                       !ENGINE_set_BN_mod_exp_crt(ret, &cswift_mod_exp_crt) ||
+                       !ENGINE_set_init_function(ret, cswift_init) ||
+                       !ENGINE_set_finish_function(ret, cswift_finish))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
 
        /* We know that the "PKCS1_SSLeay()" functions hook properly
         * to the cswift-specific mod_exp and mod_exp_crt so we use
@@ -203,7 +201,7 @@ ENGINE *ENGINE_cswift()
        meth2 = DH_OpenSSL();
        cswift_dh.generate_key = meth2->generate_key;
        cswift_dh.compute_key = meth2->compute_key;
-       return &engine_cswift;
+       return ret;
        }
 
 /* This is a process-global DSO handle used for loading and unloading
index 5c5595b8c96fcde323aeb134301cc0107aab59a2..792893a2fdda55c9485a8cfb95c68cb2b7dc5b71 100644 (file)
@@ -62,7 +62,6 @@
 #include <openssl/pem.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
-#include "engine_int.h"
 #include <openssl/engine.h>
 
 #ifndef OPENSSL_NO_HW
@@ -169,26 +168,9 @@ static RAND_METHOD hwcrhk_rand =
        hwcrhk_rand_status,
        };
 
-/* Our ENGINE structure. */
-static ENGINE engine_hwcrhk =
-        {
-       "chil",
-       "nCipher hardware engine support",
-       &hwcrhk_rsa,
-       NULL,
-       &hwcrhk_dh,
-       &hwcrhk_rand,
-       hwcrhk_mod_exp,
-       NULL,
-       hwcrhk_init,
-       hwcrhk_finish,
-       hwcrhk_ctrl,
-       hwcrhk_load_privkey,
-       hwcrhk_load_pubkey,
-       0, /* no flags */
-       0, 0, /* no references */
-       NULL, NULL /* unlinked */
-        };
+/* Constants used when creating the ENGINE */
+static const char *engine_hwcrhk_id = "chil";
+static const char *engine_hwcrhk_name = "nCipher hardware engine support";
 
 /* Internal stuff for HWCryptoHook */
 
@@ -294,6 +276,24 @@ ENGINE *ENGINE_ncipher()
        {
        const RSA_METHOD *meth1;
        const DH_METHOD *meth2;
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_hwcrhk_id) ||
+                       !ENGINE_set_name(ret, engine_hwcrhk_name) ||
+                       !ENGINE_set_RSA(ret, &hwcrhk_rsa) ||
+                       !ENGINE_set_DH(ret, &hwcrhk_dh) ||
+                       !ENGINE_set_RAND(ret, &hwcrhk_rand) ||
+                       !ENGINE_set_BN_mod_exp(ret, hwcrhk_mod_exp) ||
+                       !ENGINE_set_init_function(ret, hwcrhk_init) ||
+                       !ENGINE_set_finish_function(ret, hwcrhk_finish) ||
+                       !ENGINE_set_ctrl_function(ret, hwcrhk_ctrl) ||
+                       !ENGINE_set_load_privkey_function(ret, hwcrhk_load_privkey) ||
+                       !ENGINE_set_load_pubkey_function(ret, hwcrhk_load_pubkey))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
 
        /* We know that the "PKCS1_SSLeay()" functions hook properly
         * to the cswift-specific mod_exp and mod_exp_crt so we use
@@ -312,7 +312,7 @@ ENGINE *ENGINE_ncipher()
        meth2 = DH_OpenSSL();
        hwcrhk_dh.generate_key = meth2->generate_key;
        hwcrhk_dh.compute_key = meth2->compute_key;
-       return &engine_hwcrhk;
+       return ret;
        }
 
 /* This is a process-global DSO handle used for loading and unloading
@@ -605,7 +605,7 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
                        ENGINE_R_NO_KEY);
                goto err;
                }
-       rtmp = RSA_new_method(&engine_hwcrhk);
+       rtmp = RSA_new_method(eng);
        RSA_set_ex_data(rtmp, hndidx, (char *)hptr);
        rtmp->e = BN_new();
        rtmp->n = BN_new();
index b5e63906c96503846cb2f3df86fcda890a552b2d..d85de3f9acb6e5e6e575262c459c644e5081ae52 100644 (file)
@@ -60,7 +60,6 @@
 #include <openssl/crypto.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
-#include "engine_int.h"
 #include <openssl/engine.h>
 
 
@@ -230,25 +229,9 @@ static DH_METHOD nuron_dh =
        NULL
        };
 
-static ENGINE engine_nuron =
-       {
-       "nuron",
-       "Nuron hardware engine support",
-       &nuron_rsa,
-       &nuron_dsa,
-       &nuron_dh,
-       NULL,
-       nuron_mod_exp,
-       NULL,
-       nuron_init,
-       nuron_finish,
-       NULL, /* no ctrl() */
-       NULL, /* no load_privkey() */
-       NULL, /* no load_pubkey() */
-       0, /* no flags */
-       0, 0, /* no references */
-       NULL, NULL /* unlinked */
-       };
+/* Constants used when creating the ENGINE */
+static const char *engine_nuron_id = "nuron";
+static const char *engine_nuron_name = "Nuron hardware engine support";
 
 /* As this is only ever called once, there's no need for locking
  * (indeed - the lock will already be held by our caller!!!) */
@@ -257,6 +240,21 @@ ENGINE *ENGINE_nuron()
        const RSA_METHOD *meth1;
        const DSA_METHOD *meth2;
        const DH_METHOD *meth3;
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_nuron_id) ||
+                       !ENGINE_set_name(ret, engine_nuron_name) ||
+                       !ENGINE_set_RSA(ret, &nuron_rsa) ||
+                       !ENGINE_set_DSA(ret, &nuron_dsa) ||
+                       !ENGINE_set_DH(ret, &nuron_dh) ||
+                       !ENGINE_set_BN_mod_exp(ret, nuron_mod_exp) ||
+                       !ENGINE_set_init_function(ret, nuron_init) ||
+                       !ENGINE_set_finish_function(ret, nuron_finish))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
 
        /* We know that the "PKCS1_SSLeay()" functions hook properly
         * to the nuron-specific mod_exp and mod_exp_crt so we use
@@ -282,7 +280,7 @@ ENGINE *ENGINE_nuron()
        meth3=DH_OpenSSL();
        nuron_dh.generate_key=meth3->generate_key;
        nuron_dh.compute_key=meth3->compute_key;
-       return &engine_nuron;
+       return ret;
        }
 
 #endif /* !OPENSSL_NO_HW_NURON */
index 143efbdeea4e588d9414a964af3089d3e4cd1866..a05211f27ab4dbf4a4398a43b48bc2ab211b6080 100644 (file)
@@ -62,7 +62,6 @@
 #include <openssl/crypto.h>
 #include "cryptlib.h"
 #include <openssl/dso.h>
-#include "engine_int.h"
 #include <openssl/engine.h>
 
 #ifndef OPENSSL_NO_HW
@@ -153,26 +152,9 @@ static DH_METHOD ubsec_dh =
        NULL
        };
 
-/* Our ENGINE structure. */
-static ENGINE engine_ubsec =
-        {
-       "ubsec",
-       "UBSEC hardware engine support",
-       &ubsec_rsa,
-       &ubsec_dsa,
-       &ubsec_dh,
-       NULL,
-       ubsec_mod_exp,
-       ubsec_mod_exp_crt,
-       ubsec_init,
-       ubsec_finish,
-       NULL, /* no ctrl() */
-       NULL, /* no load_privkey() */
-       NULL, /* no load_pubkey() */
-       0, /* no flags */
-       0, 0, /* no references */
-       NULL, NULL /* unlinked */
-        };
+/* Constants used when creating the ENGINE */
+static const char *engine_ubsec_id = "ubsec";
+static const char *engine_ubsec_name = "UBSEC hardware engine support";
 
 /* As this is only ever called once, there's no need for locking
  * (indeed - the lock will already be held by our caller!!!) */
@@ -182,6 +164,22 @@ ENGINE *ENGINE_ubsec()
 #ifndef HAVE_UBSEC_DH
        const DH_METHOD *meth3;
 #endif /* HAVE_UBSEC_DH */
+       ENGINE *ret = ENGINE_new();
+       if(!ret)
+               return NULL;
+       if(!ENGINE_set_id(ret, engine_ubsec_id) ||
+                       !ENGINE_set_name(ret, engine_ubsec_name) ||
+                       !ENGINE_set_RSA(ret, &ubsec_rsa) ||
+                       !ENGINE_set_DSA(ret, &ubsec_dsa) ||
+                       !ENGINE_set_DH(ret, &ubsec_dh) ||
+                       !ENGINE_set_BN_mod_exp(ret, ubsec_mod_exp) ||
+                       !ENGINE_set_BN_mod_exp_crt(ret, ubsec_mod_exp_crt) ||
+                       !ENGINE_set_init_function(ret, ubsec_init) ||
+                       !ENGINE_set_finish_function(ret, ubsec_finish))
+               {
+               ENGINE_free(ret);
+               return NULL;
+               }
 
        /* We know that the "PKCS1_SSLeay()" functions hook properly
         * to the Broadcom-specific mod_exp and mod_exp_crt so we use
@@ -203,7 +201,7 @@ ENGINE *ENGINE_ubsec()
        ubsec_dh.compute_key = meth3->compute_key;
 #endif /* HAVE_UBSEC_DH */
 
-       return &engine_ubsec;
+       return ret;
        }
 
 /* This is a process-global DSO handle used for loading and unloading