📄 e_chil.c
字号:
static long set_HWCRHK_LIBNAME(const char *name) { free_HWCRHK_LIBNAME(); return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); }static const char *n_hwcrhk_Init = "HWCryptoHook_Init";static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";#ifndef OPENSSL_NO_RSAstatic const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";#endifstatic const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";#ifndef OPENSSL_NO_RSAstatic const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";#endifstatic const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";/* HWCryptoHook library functions and mechanics - these are used by the * higher-level functions further down. NB: As and where there's no * error checking, take a look lower down where these functions are * called, the checking and error handling is probably down there. *//* utility function to obtain a context */static int get_context(HWCryptoHook_ContextHandle *hac, HWCryptoHook_CallerContext *cac) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; rmsg.buf = tempbuf; rmsg.size = sizeof(tempbuf); *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, cac); if (!*hac) return 0; return 1; } /* similarly to release one. */static void release_context(HWCryptoHook_ContextHandle hac) { p_hwcrhk_Finish(hac); }/* Destructor (complements the "ENGINE_chil()" constructor) */static int hwcrhk_destroy(ENGINE *e) { free_HWCRHK_LIBNAME(); ERR_unload_HWCRHK_strings(); return 1; }/* (de)initialisation functions. */static int hwcrhk_init(ENGINE *e) { HWCryptoHook_Init_t *p1; HWCryptoHook_Finish_t *p2; HWCryptoHook_ModExp_t *p3;#ifndef OPENSSL_NO_RSA HWCryptoHook_RSA_t *p4; HWCryptoHook_RSALoadKey_t *p5; HWCryptoHook_RSAGetPublicKey_t *p6; HWCryptoHook_RSAUnloadKey_t *p7;#endif HWCryptoHook_RandomBytes_t *p8; HWCryptoHook_ModExpCRT_t *p9; if(hwcrhk_dso != NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED); goto err; } /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0); if(hwcrhk_dso == NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } if(!(p1 = (HWCryptoHook_Init_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) || !(p2 = (HWCryptoHook_Finish_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || !(p3 = (HWCryptoHook_ModExp_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||#ifndef OPENSSL_NO_RSA !(p4 = (HWCryptoHook_RSA_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || !(p5 = (HWCryptoHook_RSALoadKey_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) || !(p6 = (HWCryptoHook_RSAGetPublicKey_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || !(p7 = (HWCryptoHook_RSAUnloadKey_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||#endif !(p8 = (HWCryptoHook_RandomBytes_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || !(p9 = (HWCryptoHook_ModExpCRT_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } /* Copy the pointers */ p_hwcrhk_Init = p1; p_hwcrhk_Finish = p2; p_hwcrhk_ModExp = p3;#ifndef OPENSSL_NO_RSA p_hwcrhk_RSA = p4; p_hwcrhk_RSALoadKey = p5; p_hwcrhk_RSAGetPublicKey = p6; p_hwcrhk_RSAUnloadKey = p7;#endif p_hwcrhk_RandomBytes = p8; p_hwcrhk_ModExpCRT = p9; /* Check if the application decided to support dynamic locks, and if it does, use them. */ if (disable_mutex_callbacks == 0) { if (CRYPTO_get_dynlock_create_callback() != NULL && CRYPTO_get_dynlock_lock_callback() != NULL && CRYPTO_get_dynlock_destroy_callback() != NULL) { hwcrhk_globals.mutex_init = hwcrhk_mutex_init; hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; } else if (CRYPTO_get_locking_callback() != NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_LOCKING_MISSING); ERR_add_error_data(1,"You HAVE to add dynamic locking callbacks via CRYPTO_set_dynlock_{create,lock,destroy}_callback()"); goto err; } } /* Try and get a context - if not, we may have a DSO but no * accelerator! */ if(!get_context(&hwcrhk_context, &password_context)) { HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE); goto err; } /* Everything's fine. */#ifndef OPENSSL_NO_RSA if (hndidx_rsa == -1) hndidx_rsa = RSA_get_ex_new_index(0, "nFast HWCryptoHook RSA key handle", NULL, NULL, hwcrhk_ex_free);#endif return 1;err: if(hwcrhk_dso) DSO_free(hwcrhk_dso); hwcrhk_dso = NULL; p_hwcrhk_Init = NULL; p_hwcrhk_Finish = NULL; p_hwcrhk_ModExp = NULL;#ifndef OPENSSL_NO_RSA p_hwcrhk_RSA = NULL; p_hwcrhk_RSALoadKey = NULL; p_hwcrhk_RSAGetPublicKey = NULL; p_hwcrhk_RSAUnloadKey = NULL;#endif p_hwcrhk_ModExpCRT = NULL; p_hwcrhk_RandomBytes = NULL; return 0; }static int hwcrhk_finish(ENGINE *e) { int to_return = 1; free_HWCRHK_LIBNAME(); if(hwcrhk_dso == NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED); to_return = 0; goto err; } release_context(hwcrhk_context); if(!DSO_free(hwcrhk_dso)) { HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE); to_return = 0; goto err; } err: if (logstream) BIO_free(logstream); hwcrhk_dso = NULL; p_hwcrhk_Init = NULL; p_hwcrhk_Finish = NULL; p_hwcrhk_ModExp = NULL;#ifndef OPENSSL_NO_RSA p_hwcrhk_RSA = NULL; p_hwcrhk_RSALoadKey = NULL; p_hwcrhk_RSAGetPublicKey = NULL; p_hwcrhk_RSAUnloadKey = NULL;#endif p_hwcrhk_ModExpCRT = NULL; p_hwcrhk_RandomBytes = NULL; return to_return; }static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) { int to_return = 1; switch(cmd) { case HWCRHK_CMD_SO_PATH: if(hwcrhk_dso) { HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED); return 0; } if(p == NULL) { HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER); return 0; } return set_HWCRHK_LIBNAME((const char *)p); case ENGINE_CTRL_SET_LOGSTREAM: { BIO *bio = (BIO *)p; CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if (logstream) { BIO_free(logstream); logstream = NULL; } if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) logstream = bio; else HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED); } CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case ENGINE_CTRL_SET_PASSWORD_CALLBACK: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); password_context.password_callback = (pem_password_cb *)f; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case ENGINE_CTRL_SET_USER_INTERFACE: case HWCRHK_CMD_SET_USER_INTERFACE: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); password_context.ui_method = (UI_METHOD *)p; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case ENGINE_CTRL_SET_CALLBACK_DATA: case HWCRHK_CMD_SET_CALLBACK_DATA: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); password_context.callback_data = p; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; /* this enables or disables the "SimpleForkCheck" flag used in the * initialisation structure. */ case ENGINE_CTRL_CHIL_SET_FORKCHECK: case HWCRHK_CMD_FORK_CHECK: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if(i) hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck; else hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; /* This will prevent the initialisation function from "installing" * the mutex-handling callbacks, even if they are available from * within the library (or were provided to the library from the * calling application). This is to remove any baggage for * applications not using multithreading. */ case ENGINE_CTRL_CHIL_NO_LOCKING: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); disable_mutex_callbacks = 1; CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; case HWCRHK_CMD_THREAD_LOCKING: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); disable_mutex_callbacks = ((i == 0) ? 0 : 1); CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); break; /* The command isn't understood by this engine */ default: HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); to_return = 0; break; } return to_return; }static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) {#ifndef OPENSSL_NO_RSA RSA *rtmp = NULL;#endif EVP_PKEY *res = NULL;#ifndef OPENSSL_NO_RSA HWCryptoHook_MPI e, n; HWCryptoHook_RSAKeyHandle *hptr;#endif#if !defined(OPENSSL_NO_RSA) char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; HWCryptoHook_PassphraseContext ppctx;#endif#if !defined(OPENSSL_NO_RSA) rmsg.buf = tempbuf; rmsg.size = sizeof(tempbuf);#endif if(!hwcrhk_context) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED); goto err; }#ifndef OPENSSL_NO_RSA hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); if (!hptr) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); goto err; } ppctx.ui_method = ui_method; ppctx.callback_data = callback_data; if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } if (!*hptr) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY); goto err; }#endif#ifndef OPENSSL_NO_RSA rtmp = RSA_new_method(eng); RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); rtmp->e = BN_new(); rtmp->n = BN_new(); rtmp->flags |= RSA_FLAG_EXT_PKEY; MPI2BN(rtmp->e, e); MPI2BN(rtmp->n, n); if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) != HWCRYPTOHOOK_ERROR_MPISIZE) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG)); bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG)); MPI2BN(rtmp->e, e); MPI2BN(rtmp->n, n); if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } rtmp->e->top = e.size / sizeof(BN_ULONG); bn_fix_top(rtmp->e); rtmp->n->top = n.size / sizeof(BN_ULONG); bn_fix_top(rtmp->n); res = EVP_PKEY_new(); EVP_PKEY_assign_RSA(res, rtmp);#endif if (!res) HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); return res; err: if (res) EVP_PKEY_free(res);#ifndef OPENSSL_NO_RSA if (rtmp) RSA_free(rtmp);#endif return NULL; }static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, UI_METHOD *ui_method, void *callback_data) { EVP_PKEY *res = NULL;#ifndef OPENSSL_NO_RSA res = hwcrhk_load_privkey(eng, key_id, ui_method, callback_data);#endif if (res) switch(res->type) {#ifndef OPENSSL_NO_RSA case EVP_PKEY_RSA: { RSA *rsa = NULL; CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); rsa = res->pkey.rsa; res->pkey.rsa = RSA_new(); res->pkey.rsa->n = rsa->n; res->pkey.rsa->e = rsa->e; rsa->n = NULL; rsa->e = NULL; CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); RSA_free(rsa); } break;#endif default: HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); goto err; } return res; err: if (res) EVP_PKEY_free(res); return NULL; }/* A little mod_exp */static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; /* Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them directly, plus a little macro magic. We only thing we need to make sure of is that enough space is allocated. */ HWCryptoHook_MPI m_a, m_p, m_n, m_r; int to_return, ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -