(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/engines/e_chil.c

    1: /* crypto/engine/e_chil.c -*- mode: C; c-file-style: "eay" -*- */
    2: /* Written by Richard Levitte (richard@levitte.org), Geoff Thorpe
    3:  * (geoff@geoffthorpe.net) and Dr Stephen N Henson (shenson@bigfoot.com)
    4:  * for the OpenSSL project 2000.
    5:  */
    6: /* ====================================================================
    7:  * Copyright (c) 1999-2001 The OpenSSL Project.  All rights reserved.
    8:  *
    9:  * Redistribution and use in source and binary forms, with or without
   10:  * modification, are permitted provided that the following conditions
   11:  * are met:
   12:  *
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer. 
   15:  *
   16:  * 2. Redistributions in binary form must reproduce the above copyright
   17:  *    notice, this list of conditions and the following disclaimer in
   18:  *    the documentation and/or other materials provided with the
   19:  *    distribution.
   20:  *
   21:  * 3. All advertising materials mentioning features or use of this
   22:  *    software must display the following acknowledgment:
   23:  *    "This product includes software developed by the OpenSSL Project
   24:  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
   25:  *
   26:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   27:  *    endorse or promote products derived from this software without
   28:  *    prior written permission. For written permission, please contact
   29:  *    licensing@OpenSSL.org.
   30:  *
   31:  * 5. Products derived from this software may not be called "OpenSSL"
   32:  *    nor may "OpenSSL" appear in their names without prior written
   33:  *    permission of the OpenSSL Project.
   34:  *
   35:  * 6. Redistributions of any form whatsoever must retain the following
   36:  *    acknowledgment:
   37:  *    "This product includes software developed by the OpenSSL Project
   38:  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
   39:  *
   40:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   41:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   42:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   43:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   44:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   45:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   46:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   47:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   48:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   49:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   50:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   51:  * OF THE POSSIBILITY OF SUCH DAMAGE.
   52:  * ====================================================================
   53:  *
   54:  * This product includes cryptographic software written by Eric Young
   55:  * (eay@cryptsoft.com).  This product includes software written by Tim
   56:  * Hudson (tjh@cryptsoft.com).
   57:  *
   58:  */
   59: 
   60: #include <stdio.h>
   61: #include <string.h>
   62: #include <openssl/crypto.h>
   63: #include <openssl/pem.h>
   64: #include <openssl/dso.h>
   65: #include <openssl/engine.h>
   66: #include <openssl/ui.h>
   67: #include <openssl/rand.h>
   68: #ifndef OPENSSL_NO_RSA
   69: #include <openssl/rsa.h>
   70: #endif
   71: #ifndef OPENSSL_NO_DH
   72: #include <openssl/dh.h>
   73: #endif
   74: #include <openssl/bn.h>
   75: 
   76: #ifndef OPENSSL_NO_HW
   77: #ifndef OPENSSL_NO_HW_CHIL
   78: 
   79: /* Attribution notice: nCipher have said several times that it's OK for
   80:  * us to implement a general interface to their boxes, and recently declared
   81:  * their HWCryptoHook to be public, and therefore available for us to use.
   82:  * Thanks, nCipher.
   83:  *
   84:  * The hwcryptohook.h included here is from May 2000.
   85:  * [Richard Levitte]
   86:  */
   87: #ifdef FLAT_INC
   88: #include "hwcryptohook.h"
   89: #else
   90: #include "vendor_defns/hwcryptohook.h"
   91: #endif
   92: 
   93: #define HWCRHK_LIB_NAME "CHIL engine"
   94: #include "e_chil_err.c"
   95: 
   96: static int hwcrhk_destroy(ENGINE *e);
   97: static int hwcrhk_init(ENGINE *e);
   98: static int hwcrhk_finish(ENGINE *e);
   99: static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); 
  100: 
  101: /* Functions to handle mutexes */
  102: static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
  103: static int hwcrhk_mutex_lock(HWCryptoHook_Mutex*);
  104: static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
  105: static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
  106: 
  107: /* BIGNUM stuff */
  108: static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  109:                 const BIGNUM *m, BN_CTX *ctx);
  110: 
  111: #ifndef OPENSSL_NO_RSA
  112: /* RSA stuff */
  113: static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
  114: #endif
  115: #ifndef OPENSSL_NO_RSA
  116: /* This function is aliased to mod_exp (with the mont stuff dropped). */
  117: static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
  118:                 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  119: #endif
  120: 
  121: #ifndef OPENSSL_NO_DH
  122: /* DH stuff */
  123: /* This function is alised to mod_exp (with the DH and mont dropped). */
  124: static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
  125:         const BIGNUM *a, const BIGNUM *p,
  126:         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
  127: #endif
  128: 
  129: /* RAND stuff */
  130: static int hwcrhk_rand_bytes(unsigned char *buf, int num);
  131: static int hwcrhk_rand_status(void);
  132: 
  133: /* KM stuff */
  134: static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
  135:         UI_METHOD *ui_method, void *callback_data);
  136: static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
  137:         UI_METHOD *ui_method, void *callback_data);
  138: #ifndef OPENSSL_NO_RSA
  139: static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
  140:         int ind,long argl, void *argp);
  141: #endif
  142: 
  143: /* Interaction stuff */
  144: static int hwcrhk_insert_card(const char *prompt_info,
  145:         const char *wrong_info,
  146:         HWCryptoHook_PassphraseContext *ppctx,
  147:         HWCryptoHook_CallerContext *cactx);
  148: static int hwcrhk_get_pass(const char *prompt_info,
  149:         int *len_io, char *buf,
  150:         HWCryptoHook_PassphraseContext *ppctx,
  151:         HWCryptoHook_CallerContext *cactx);
  152: static void hwcrhk_log_message(void *logstr, const char *message);
  153: 
  154: /* The definitions for control commands specific to this engine */
  155: #define HWCRHK_CMD_SO_PATH              ENGINE_CMD_BASE
  156: #define HWCRHK_CMD_FORK_CHECK           (ENGINE_CMD_BASE + 1)
  157: #define HWCRHK_CMD_THREAD_LOCKING       (ENGINE_CMD_BASE + 2)
  158: #define HWCRHK_CMD_SET_USER_INTERFACE   (ENGINE_CMD_BASE + 3)
  159: #define HWCRHK_CMD_SET_CALLBACK_DATA    (ENGINE_CMD_BASE + 4)
  160: static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
  161:         {HWCRHK_CMD_SO_PATH,
  162:                 "SO_PATH",
  163:                 "Specifies the path to the 'hwcrhk' shared library",
  164:                 ENGINE_CMD_FLAG_STRING},
  165:         {HWCRHK_CMD_FORK_CHECK,
  166:                 "FORK_CHECK",
  167:                 "Turns fork() checking on or off (boolean)",
  168:                 ENGINE_CMD_FLAG_NUMERIC},
  169:         {HWCRHK_CMD_THREAD_LOCKING,
  170:                 "THREAD_LOCKING",
  171:                 "Turns thread-safe locking on or off (boolean)",
  172:                 ENGINE_CMD_FLAG_NUMERIC},
  173:         {HWCRHK_CMD_SET_USER_INTERFACE,
  174:                 "SET_USER_INTERFACE",
  175:                 "Set the global user interface (internal)",
  176:                 ENGINE_CMD_FLAG_INTERNAL},
  177:         {HWCRHK_CMD_SET_CALLBACK_DATA,
  178:                 "SET_CALLBACK_DATA",
  179:                 "Set the global user interface extra data (internal)",
  180:                 ENGINE_CMD_FLAG_INTERNAL},
  181:         {0, NULL, NULL, 0}
  182:         };
  183: 
  184: #ifndef OPENSSL_NO_RSA
  185: /* Our internal RSA_METHOD that we provide pointers to */
  186: static RSA_METHOD hwcrhk_rsa =
  187:         {
  188:         "CHIL RSA method",
  189:         NULL,
  190:         NULL,
  191:         NULL,
  192:         NULL,
  193:         hwcrhk_rsa_mod_exp,
  194:         hwcrhk_mod_exp_mont,
  195:         NULL,
  196:         NULL,
  197:         0,
  198:         NULL,
  199:         NULL,
  200:         NULL,
  201:         NULL
  202:         };
  203: #endif
  204: 
  205: #ifndef OPENSSL_NO_DH
  206: /* Our internal DH_METHOD that we provide pointers to */
  207: static DH_METHOD hwcrhk_dh =
  208:         {
  209:         "CHIL DH method",
  210:         NULL,
  211:         NULL,
  212:         hwcrhk_mod_exp_dh,
  213:         NULL,
  214:         NULL,
  215:         0,
  216:         NULL,
  217:         NULL
  218:         };
  219: #endif
  220: 
  221: static RAND_METHOD hwcrhk_rand =
  222:         {
  223:         /* "CHIL RAND method", */
  224:         NULL,
  225:         hwcrhk_rand_bytes,
  226:         NULL,
  227:         NULL,
  228:         hwcrhk_rand_bytes,
  229:         hwcrhk_rand_status,
  230:         };
  231: 
  232: /* Constants used when creating the ENGINE */
  233: static const char *engine_hwcrhk_id = "chil";
  234: static const char *engine_hwcrhk_name = "CHIL hardware engine support";
  235: 
  236: #ifndef OPENSSL_NO_DYNAMIC_ENGINE 
  237: /* Compatibility hack, the dynamic library uses this form in the path */
  238: static const char *engine_hwcrhk_id_alt = "ncipher";
  239: #endif
  240: 
  241: /* Internal stuff for HWCryptoHook */
  242: 
  243: /* Some structures needed for proper use of thread locks */
  244: /* hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue
  245:    into HWCryptoHook_Mutex */
  246: struct HWCryptoHook_MutexValue
  247:         {
  248:         int lockid;
  249:         };
  250: 
  251: /* hwcryptohook.h has some typedefs that turn
  252:    struct HWCryptoHook_PassphraseContextValue
  253:    into HWCryptoHook_PassphraseContext */
  254: struct HWCryptoHook_PassphraseContextValue
  255:         {
  256:         UI_METHOD *ui_method;
  257:         void *callback_data;
  258:         };
  259: 
  260: /* hwcryptohook.h has some typedefs that turn
  261:    struct HWCryptoHook_CallerContextValue
  262:    into HWCryptoHook_CallerContext */
  263: struct HWCryptoHook_CallerContextValue
  264:         {
  265:         pem_password_cb *password_callback; /* Deprecated!  Only present for
  266:                                                backward compatibility! */
  267:         UI_METHOD *ui_method;
  268:         void *callback_data;
  269:         };
  270: 
  271: /* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
  272:    BIGNUM's, so lets define a couple of conversion macros */
  273: #define BN2MPI(mp, bn) \
  274:     {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
  275: #define MPI2BN(bn, mp) \
  276:     {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
  277: 
  278: static BIO *logstream = NULL;
  279: static int disable_mutex_callbacks = 0;
  280: 
  281: /* One might wonder why these are needed, since one can pass down at least
  282:    a UI_METHOD and a pointer to callback data to the key-loading functions.
  283:    The thing is that the ModExp and RSAImmed functions can load keys as well,
  284:    if the data they get is in a special, nCipher-defined format (hint: if you
  285:    look at the private exponent of the RSA data as a string, you'll see this
  286:    string: "nCipher KM tool key id", followed by some bytes, followed a key
  287:    identity string, followed by more bytes.  This happens when you use "embed"
  288:    keys instead of "hwcrhk" keys).  Unfortunately, those functions do not take
  289:    any passphrase or caller context, and our functions can't really take any
  290:    callback data either.  Still, the "insert_card" and "get_passphrase"
  291:    callbacks may be called down the line, and will need to know what user
  292:    interface callbacks to call, and having callback data from the application
  293:    may be a nice thing as well, so we need to keep track of that globally. */
  294: static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
  295: 
  296: /* Stuff to pass to the HWCryptoHook library */
  297: static HWCryptoHook_InitInfo hwcrhk_globals = {
  298:         HWCryptoHook_InitFlags_SimpleForkCheck,        /* Flags */
  299:         &logstream,            /* logstream */
  300:         sizeof(BN_ULONG),      /* limbsize */
  301:         0,                     /* mslimb first: false for BNs */
  302:         -1,                    /* msbyte first: use native */
  303:         0,                     /* Max mutexes, 0 = no small limit */
  304:         0,                     /* Max simultaneous, 0 = default */
  305: 
  306:         /* The next few are mutex stuff: we write wrapper functions
  307:            around the OS mutex functions.  We initialise them to 0
  308:            here, and change that to actual function pointers in hwcrhk_init()
  309:            if dynamic locks are supported (that is, if the application
  310:            programmer has made sure of setting up callbacks bafore starting
  311:            this engine) *and* if disable_mutex_callbacks hasn't been set by
  312:            a call to ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). */
  313:         sizeof(HWCryptoHook_Mutex),
  314:         0,
  315:         0,
  316:         0,
  317:         0,
  318: 
  319:         /* The next few are condvar stuff: we write wrapper functions
  320:            round the OS functions.  Currently not implemented and not
  321:            and absolute necessity even in threaded programs, therefore
  322:            0'ed.  Will hopefully be implemented some day, since it
  323:            enhances the efficiency of HWCryptoHook.  */
  324:         0, /* sizeof(HWCryptoHook_CondVar), */
  325:         0, /* hwcrhk_cv_init, */
  326:         0, /* hwcrhk_cv_wait, */
  327:         0, /* hwcrhk_cv_signal, */
  328:         0, /* hwcrhk_cv_broadcast, */
  329:         0, /* hwcrhk_cv_destroy, */
  330: 
  331:         hwcrhk_get_pass,       /* pass phrase */
  332:         hwcrhk_insert_card,    /* insert a card */
  333:         hwcrhk_log_message     /* Log message */
  334: };
  335: 
  336: 
  337: /* Now, to our own code */
  338: 
  339: /* This internal function is used by ENGINE_chil() and possibly by the
  340:  * "dynamic" ENGINE support too */
  341: static int bind_helper(ENGINE *e)
  342:         {
  343: #ifndef OPENSSL_NO_RSA
  344:         const RSA_METHOD *meth1;
  345: #endif
  346: #ifndef OPENSSL_NO_DH
  347:         const DH_METHOD *meth2;
  348: #endif
  349:         if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
  350:                         !ENGINE_set_name(e, engine_hwcrhk_name) ||
  351: #ifndef OPENSSL_NO_RSA
  352:                         !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
  353: #endif
  354: #ifndef OPENSSL_NO_DH
  355:                         !ENGINE_set_DH(e, &hwcrhk_dh) ||
  356: #endif
  357:                         !ENGINE_set_RAND(e, &hwcrhk_rand) ||
  358:                         !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
  359:                         !ENGINE_set_init_function(e, hwcrhk_init) ||
  360:                         !ENGINE_set_finish_function(e, hwcrhk_finish) ||
  361:                         !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
  362:                         !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
  363:                         !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
  364:                         !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
  365:                 return 0;
  366: 
  367: #ifndef OPENSSL_NO_RSA
  368:         /* We know that the "PKCS1_SSLeay()" functions hook properly
  369:          * to the cswift-specific mod_exp and mod_exp_crt so we use
  370:          * those functions. NB: We don't use ENGINE_openssl() or
  371:          * anything "more generic" because something like the RSAref
  372:          * code may not hook properly, and if you own one of these
  373:          * cards then you have the right to do RSA operations on it
  374:          * anyway! */ 
  375:         meth1 = RSA_PKCS1_SSLeay();
  376:         hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc;
  377:         hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
  378:         hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
  379:         hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
  380: #endif
  381: 
  382: #ifndef OPENSSL_NO_DH
  383:         /* Much the same for Diffie-Hellman */
  384:         meth2 = DH_OpenSSL();
  385:         hwcrhk_dh.generate_key = meth2->generate_key;
  386:         hwcrhk_dh.compute_key = meth2->compute_key;
  387: #endif
  388: 
  389:         /* Ensure the hwcrhk error handling is set up */
  390:         ERR_load_HWCRHK_strings();
  391:         return 1;
  392:         }
  393: 
  394: #ifdef OPENSSL_NO_DYNAMIC_ENGINE
  395: static ENGINE *engine_chil(void)
  396:         {
  397:         ENGINE *ret = ENGINE_new();
  398:         if(!ret)
  399:                 return NULL;
  400:         if(!bind_helper(ret))
  401:                 {
  402:                 ENGINE_free(ret);
  403:                 return NULL;
  404:                 }
  405:         return ret;
  406:         }
  407: 
  408: void ENGINE_load_chil(void)
  409:         {
  410:         /* Copied from eng_[openssl|dyn].c */
  411:         ENGINE *toadd = engine_chil();
  412:         if(!toadd) return;
  413:         ENGINE_add(toadd);
  414:         ENGINE_free(toadd);
  415:         ERR_clear_error();
  416:         }
  417: #endif
  418: 
  419: /* This is a process-global DSO handle used for loading and unloading
  420:  * the HWCryptoHook library. NB: This is only set (or unset) during an
  421:  * init() or finish() call (reference counts permitting) and they're
  422:  * operating with global locks, so this should be thread-safe
  423:  * implicitly. */
  424: static DSO *hwcrhk_dso = NULL;
  425: static HWCryptoHook_ContextHandle hwcrhk_context = 0;
  426: #ifndef OPENSSL_NO_RSA
  427: static int hndidx_rsa = -1;    /* Index for KM handle.  Not really used yet. */
  428: #endif
  429: 
  430: /* These are the function pointers that are (un)set when the library has
  431:  * successfully (un)loaded. */
  432: static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
  433: static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
  434: static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
  435: #ifndef OPENSSL_NO_RSA
  436: static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
  437: #endif
  438: static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
  439: #ifndef OPENSSL_NO_RSA
  440: static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
  441: static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
  442: static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
  443: #endif
  444: static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
  445: 
  446: /* Used in the DSO operations. */
  447: static const char *HWCRHK_LIBNAME = NULL;
  448: static void free_HWCRHK_LIBNAME(void)
  449:         {
  450:         if(HWCRHK_LIBNAME)
  451:                 OPENSSL_free((void*)HWCRHK_LIBNAME);
  452:         HWCRHK_LIBNAME = NULL;
  453:         }
  454: static const char *get_HWCRHK_LIBNAME(void)
  455:         {
  456:         if(HWCRHK_LIBNAME)
  457:                 return HWCRHK_LIBNAME;
  458:         return "nfhwcrhk";
  459:         }
  460: static long set_HWCRHK_LIBNAME(const char *name)
  461:         {
  462:         free_HWCRHK_LIBNAME();
  463:         return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0);
  464:         }
  465: static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
  466: static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
  467: static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
  468: #ifndef OPENSSL_NO_RSA
  469: static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
  470: #endif
  471: static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
  472: #ifndef OPENSSL_NO_RSA
  473: static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
  474: static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
  475: static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
  476: #endif
  477: static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
  478: 
  479: /* HWCryptoHook library functions and mechanics - these are used by the
  480:  * higher-level functions further down. NB: As and where there's no
  481:  * error checking, take a look lower down where these functions are
  482:  * called, the checking and error handling is probably down there. */
  483: 
  484: /* utility function to obtain a context */
  485: static int get_context(HWCryptoHook_ContextHandle *hac,
  486:         HWCryptoHook_CallerContext *cac)
  487:         {
  488:         char tempbuf[1024];
  489:         HWCryptoHook_ErrMsgBuf rmsg;
  490: 
  491:         rmsg.buf = tempbuf;
  492:         rmsg.size = sizeof(tempbuf);
  493: 
  494:         *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
  495:                 cac);
  496:         if (!*hac)
  497:                 return 0;
  498:         return 1;
  499:         }
  500:  
  501: /* similarly to release one. */
  502: static void release_context(HWCryptoHook_ContextHandle hac)
  503:         {
  504:         p_hwcrhk_Finish(hac);
  505:         }
  506: 
  507: /* Destructor (complements the "ENGINE_chil()" constructor) */
  508: static int hwcrhk_destroy(ENGINE *e)
  509:         {
  510:         free_HWCRHK_LIBNAME();
  511:         ERR_unload_HWCRHK_strings();
  512:         return 1;
  513:         }
  514: 
  515: /* (de)initialisation functions. */
  516: static int hwcrhk_init(ENGINE *e)
  517:         {
  518:         HWCryptoHook_Init_t *p1;
  519:         HWCryptoHook_Finish_t *p2;
  520:         HWCryptoHook_ModExp_t *p3;
  521: #ifndef OPENSSL_NO_RSA
  522:         HWCryptoHook_RSA_t *p4;
  523:         HWCryptoHook_RSALoadKey_t *p5;
  524:         HWCryptoHook_RSAGetPublicKey_t *p6;
  525:         HWCryptoHook_RSAUnloadKey_t *p7;
  526: #endif
  527:         HWCryptoHook_RandomBytes_t *p8;
  528:         HWCryptoHook_ModExpCRT_t *p9;
  529: 
  530:         if(hwcrhk_dso != NULL)
  531:                 {
  532:                 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
  533:                 goto err;
  534:                 }
  535:         /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
  536:         hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0);
  537:         if(hwcrhk_dso == NULL)
  538:                 {
  539:                 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
  540:                 goto err;
  541:                 }
  542:         if(!(p1 = (HWCryptoHook_Init_t *)
  543:                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) ||
  544:                 !(p2 = (HWCryptoHook_Finish_t *)
  545:                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
  546:                 !(p3 = (HWCryptoHook_ModExp_t *)
  547:                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
  548: #ifndef OPENSSL_NO_RSA
  549:                 !(p4 = (HWCryptoHook_RSA_t *)
  550:                         DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
  551: