X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fengine%2Fhw_ncipher.c;h=b6403aa666515b140da575d7af1aeebc0eb58a55;hp=98fd5227bc6c247994c03fda6382567bdc1cff7a;hb=20e8f0ee27430f46b0d26a53786e9af25366dcc9;hpb=cf1b7d96647d55e533f779e476e3d4371f40445a diff --git a/crypto/engine/hw_ncipher.c b/crypto/engine/hw_ncipher.c index 98fd5227bc..b6403aa666 100644 --- a/crypto/engine/hw_ncipher.c +++ b/crypto/engine/hw_ncipher.c @@ -58,12 +58,13 @@ */ #include +#include #include #include #include "cryptlib.h" #include -#include "engine_int.h" #include +#include #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW_NCIPHER @@ -82,9 +83,9 @@ #include "vendor_defns/hwcryptohook.h" #endif -static int hwcrhk_init(void); -static int hwcrhk_finish(void); -static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); +static int hwcrhk_init(ENGINE *e); +static int hwcrhk_finish(ENGINE *e); +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); /* Functions to handle mutexes */ static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*); @@ -96,8 +97,10 @@ static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*); static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx); +#ifndef OPENSSL_NO_RSA /* RSA stuff */ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa); +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); @@ -113,20 +116,55 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num); static int hwcrhk_rand_status(void); /* KM stuff */ -static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, - const char *passphrase); -static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, - const char *passphrase); +static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int ind,long argl, void *argp); /* Interaction stuff */ +static int hwcrhk_insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext *ppctx, + HWCryptoHook_CallerContext *cactx); static int hwcrhk_get_pass(const char *prompt_info, int *len_io, char *buf, HWCryptoHook_PassphraseContext *ppctx, HWCryptoHook_CallerContext *cactx); static void hwcrhk_log_message(void *logstr, const char *message); +/* The definitions for control commands specific to this engine */ +#define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE +#define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1) +#define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2) +#define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3) +#define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4) +static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = { + {HWCRHK_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'hwcrhk' shared library", + ENGINE_CMD_FLAG_STRING}, + {HWCRHK_CMD_FORK_CHECK, + "FORK_CHECK", + "Turns fork() checking on or off (boolean)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_THREAD_LOCKING, + "THREAD_LOCKING", + "Turns thread-safe locking on or off (boolean)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_SET_USER_INTERFACE, + "SET_USER_INTERFACE", + "Set the global user interface (internal)", + ENGINE_CMD_FLAG_INTERNAL}, + {HWCRHK_CMD_SET_CALLBACK_DATA, + "SET_CALLBACK_DATA", + "Set the global user interface extra data (internal)", + ENGINE_CMD_FLAG_INTERNAL}, + {0, NULL, NULL, 0} + }; + +#ifndef OPENSSL_NO_RSA /* Our internal RSA_METHOD that we provide pointers to */ static RSA_METHOD hwcrhk_rsa = { @@ -144,7 +182,9 @@ static RSA_METHOD hwcrhk_rsa = NULL, NULL }; +#endif +#ifndef OPENSSL_NO_DH /* Our internal DH_METHOD that we provide pointers to */ static DH_METHOD hwcrhk_dh = { @@ -157,6 +197,7 @@ static DH_METHOD hwcrhk_dh = 0, NULL }; +#endif static RAND_METHOD hwcrhk_rand = { @@ -169,26 +210,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 */ @@ -205,7 +229,8 @@ struct HWCryptoHook_MutexValue into HWCryptoHook_PassphraseContext */ struct HWCryptoHook_PassphraseContextValue { - void *any; + UI_METHOD *ui_method; + void *callback_data; }; /* hwcryptohook.h has some typedefs that turn @@ -213,7 +238,10 @@ struct HWCryptoHook_PassphraseContextValue into HWCryptoHook_CallerContext */ struct HWCryptoHook_CallerContextValue { - void *any; + pem_password_cb *password_callback; /* Deprecated! Only present for + backward compatibility! */ + UI_METHOD *ui_method; + void *callback_data; }; /* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL @@ -223,28 +251,24 @@ struct HWCryptoHook_CallerContextValue #define MPI2BN(bn, mp) \ {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} -#if 0 /* Card and password management is not yet supported */ -/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet - defined, because we haven't quite decided on the proper form yet. - log_message() just adds an entry in the error stack. I don't know - if that's good or bad... */ -static int insert_card(const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext *ppctx, - HWCryptoHook_CallerContext *cactx); -static int get_pass(const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext *ppctx, - HWCryptoHook_CallerContext *cactx); -#endif - static BIO *logstream = NULL; -static pem_password_cb *password_callback = NULL; -#if 0 -static void *password_callback_userdata = NULL; -#endif static int disable_mutex_callbacks = 0; +/* One might wonder why these are needed, since one can pass down at least + a UI_METHOD and a pointer to callback data to the key-loading functions. + The thing is that the ModExp and RSAImmed functions can load keys as well, + if the data they get is in a special, nCipher-defined format (hint: if you + look at the private exponent of the RSA data as a string, you'll see this + string: "nCipher KM tool key id", followed by some bytes, followed a key + identity string, followed by more bytes. This happens when you use "embed" + keys instead of "hwcrhk" keys). Unfortunately, those functions do not take + any passphrase or caller context, and our functions can't really take any + callback data either. Still, the "insert_card" and "get_passphrase" + callbacks may be called down the line, and will need to know what user + interface callbacks to call, and having callback data from the application + may be a nice thing as well, so we need to keep track of that globally. */ +static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL }; + /* Stuff to pass to the HWCryptoHook library */ static HWCryptoHook_InitInfo hwcrhk_globals = { 0, /* Flags */ @@ -281,7 +305,7 @@ static HWCryptoHook_InitInfo hwcrhk_globals = { 0, /* hwcrhk_cv_destroy, */ hwcrhk_get_pass, /* pass phrase */ - 0, /* insert_card, */ /* insert a card */ + hwcrhk_insert_card, /* insert a card */ hwcrhk_log_message /* Log message */ }; @@ -292,9 +316,37 @@ static HWCryptoHook_InitInfo hwcrhk_globals = { * (indeed - the lock will already be held by our caller!!!) */ ENGINE *ENGINE_ncipher() { +#ifndef OPENSSL_NO_RSA const RSA_METHOD *meth1; +#endif +#ifndef OPENSSL_NO_DH const DH_METHOD *meth2; +#endif + ENGINE *ret = ENGINE_new(); + if(!ret) + return NULL; + if(!ENGINE_set_id(ret, engine_hwcrhk_id) || + !ENGINE_set_name(ret, engine_hwcrhk_name) || +#ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(ret, &hwcrhk_rsa) || +#endif +#ifndef OPENSSL_NO_DH + !ENGINE_set_DH(ret, &hwcrhk_dh) || +#endif + !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_set_cmd_defns(ret, hwcrhk_cmd_defns)) + { + ENGINE_free(ret); + return NULL; + } +#ifndef OPENSSL_NO_RSA /* We know that the "PKCS1_SSLeay()" functions hook properly * to the cswift-specific mod_exp and mod_exp_crt so we use * those functions. NB: We don't use ENGINE_openssl() or @@ -307,12 +359,15 @@ ENGINE *ENGINE_ncipher() hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +#endif +#ifndef OPENSSL_NO_DH /* Much the same for Diffie-Hellman */ meth2 = DH_OpenSSL(); hwcrhk_dh.generate_key = meth2->generate_key; hwcrhk_dh.compute_key = meth2->compute_key; - return &engine_hwcrhk; +#endif + return ret; } /* This is a process-global DSO handle used for loading and unloading @@ -322,30 +377,41 @@ ENGINE *ENGINE_ncipher() * implicitly. */ static DSO *hwcrhk_dso = NULL; static HWCryptoHook_ContextHandle hwcrhk_context = 0; -static int hndidx = -1; /* Index for KM handle. Not really used yet. */ +#ifndef OPENSSL_NO_RSA +static int hndidx_rsa = -1; /* Index for KM handle. Not really used yet. */ +#endif /* These are the function pointers that are (un)set when the library has * successfully (un)loaded. */ static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; +#ifndef OPENSSL_NO_RSA static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; +#endif static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; +#ifndef OPENSSL_NO_RSA static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; +#endif static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; /* Used in the DSO operations. */ -static const char *HWCRHK_LIBNAME = "nfhwcrhk"; +static const char def_HWCRHK_LIBNAME[] = "nfhwcrhk"; +static const char *HWCRHK_LIBNAME = def_HWCRHK_LIBNAME; 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_RSA static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; +#endif static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; +#ifndef OPENSSL_NO_RSA static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; +#endif static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; /* HWCryptoHook library functions and mechanics - these are used by the @@ -354,7 +420,8 @@ static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; * called, the checking and error handling is probably down there. */ /* utility function to obtain a context */ -static int get_context(HWCryptoHook_ContextHandle *hac) +static int get_context(HWCryptoHook_ContextHandle *hac, + HWCryptoHook_CallerContext *cac) { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; @@ -363,7 +430,7 @@ static int get_context(HWCryptoHook_ContextHandle *hac) rmsg.size = 1024; *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, - NULL); + cac); if (!*hac) return 0; return 1; @@ -376,15 +443,17 @@ static void release_context(HWCryptoHook_ContextHandle hac) } /* (de)initialisation functions. */ -static int hwcrhk_init(void) +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; @@ -406,6 +475,7 @@ static int hwcrhk_init(void) 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 *) @@ -414,6 +484,7 @@ static int hwcrhk_init(void) 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 *) @@ -426,10 +497,12 @@ static int hwcrhk_init(void) 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; @@ -448,16 +521,18 @@ static int hwcrhk_init(void) /* Try and get a context - if not, we may have a DSO but no * accelerator! */ - if(!get_context(&hwcrhk_context)) + if(!get_context(&hwcrhk_context, &password_context)) { ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE); goto err; } /* Everything's fine. */ - if (hndidx == -1) - hndidx = RSA_get_ex_new_index(0, +#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) @@ -466,16 +541,18 @@ err: 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(void) +static int hwcrhk_finish(ENGINE *e) { int to_return = 1; if(hwcrhk_dso == NULL) @@ -498,21 +575,36 @@ static int hwcrhk_finish(void) 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(int cmd, long i, void *p, void (*f)()) +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) { int to_return = 1; switch(cmd) { + case HWCRHK_CMD_SO_PATH: + if(hwcrhk_dso) + { + ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_ALREADY_LOADED); + return 0; + } + if(p == NULL) + { + ENGINEerr(ENGINE_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + HWCRHK_LIBNAME = (const char *)p; + return 1; case ENGINE_CTRL_SET_LOGSTREAM: { BIO *bio = (BIO *)p; @@ -532,12 +624,23 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) break; case ENGINE_CTRL_SET_PASSWORD_CALLBACK: CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - password_callback = (pem_password_cb *)f; + password_context.password_callback = (pem_password_cb *)f; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + case ENGINE_CTRL_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: + 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 |= @@ -557,6 +660,11 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) 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: @@ -569,14 +677,21 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) return to_return; } -static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, - const char *passphrase) +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) HWCryptoHook_ErrMsgBuf rmsg; +#endif + HWCryptoHook_PassphraseContext ppctx; if(!hwcrhk_context) { @@ -584,6 +699,7 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, ENGINE_R_NOT_INITIALISED); goto err; } +#ifndef OPENSSL_NO_RSA hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); if (!hptr) { @@ -591,8 +707,10 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, 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, NULL)) + &rmsg, &ppctx)) { ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, ENGINE_R_CHIL_ERROR); @@ -605,8 +723,10 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, ENGINE_R_NO_KEY); goto err; } - rtmp = RSA_new_method(&engine_hwcrhk); - RSA_set_ex_data(rtmp, hndidx, (char *)hptr); +#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; @@ -619,7 +739,7 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, 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); @@ -639,23 +759,37 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, res = EVP_PKEY_new(); EVP_PKEY_assign_RSA(res, rtmp); +#endif + + if (!res) + ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, + ENGINE_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(const char *key_id, const char *passphrase) +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) { - EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase); + 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; @@ -668,6 +802,7 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); RSA_free(rsa); } +#endif default: ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); @@ -737,7 +872,8 @@ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, err: return to_return; } - + +#ifndef OPENSSL_NO_RSA static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) { char tempbuf[1024]; @@ -754,7 +890,7 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) /* This provides support for nForce keys. Since that's opaque data all we do is provide a handle to the proper key and let HWCryptoHook take care of the rest. */ - if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx)) + if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) != NULL) { HWCryptoHook_MPI m_a, m_r; @@ -852,6 +988,7 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) err: return to_return; } +#endif /* This function is aliased to mod_exp (with the mont stuff dropped). */ static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, @@ -919,16 +1056,24 @@ static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, { char tempbuf[1024]; HWCryptoHook_ErrMsgBuf rmsg; +#ifndef OPENSSL_NO_RSA HWCryptoHook_RSAKeyHandle *hptr; +#endif +#if !defined(OPENSSL_NO_RSA) int ret; +#endif rmsg.buf = tempbuf; rmsg.size = 1024; +#ifndef OPENSSL_NO_RSA hptr = (HWCryptoHook_RSAKeyHandle *) item; - if(!hptr) return; - ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); - OPENSSL_free(hptr); + if(hptr) + { + ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); + OPENSSL_free(hptr); + } +#endif } /* Mutex calls: since the HWCryptoHook model closely follows the POSIX model @@ -940,14 +1085,14 @@ static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt, { mt->lockid = CRYPTO_get_new_dynlockid(); if (mt->lockid == 0) - return 0; - return 1; + return -1; + return 0; } static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt) { CRYPTO_w_lock(mt->lockid); - return 1; + return 0; } void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) @@ -965,43 +1110,131 @@ static int hwcrhk_get_pass(const char *prompt_info, HWCryptoHook_PassphraseContext *ppctx, HWCryptoHook_CallerContext *cactx) { - int l = 0; - char prompt[1024]; - - if (password_callback == NULL) + pem_password_cb *callback = NULL; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; + + if (cactx) + { + if (cactx->ui_method) + ui_method = cactx->ui_method; + if (cactx->password_callback) + callback = cactx->password_callback; + if (cactx->callback_data) + callback_data = cactx->callback_data; + } + if (ppctx) { - ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); - return -1; + if (ppctx->ui_method) + { + ui_method = ppctx->ui_method; + callback = NULL; + } + if (ppctx->callback_data) + callback_data = ppctx->callback_data; } - if (prompt_info) + if (callback == NULL && ui_method == NULL) { - strncpy(prompt, "Card: \"", sizeof(prompt)); - l += 5; - strncpy(prompt + l, prompt_info, sizeof(prompt) - l); - l += strlen(prompt_info); - if (l + 2 < sizeof(prompt)) - { - strncpy(prompt + l, "\"\n", sizeof(prompt) - l); - l += 2; - } - } - if (l < sizeof(prompt) - 1) - { - strncpy(prompt, "Enter Passphrase :", - sizeof(prompt) - l); - l += 35; + ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); + return -1; } - prompt[l] = '\0'; - /* I know, passing on the prompt instead of the user data *is* - a bad thing. However, that's all we have right now. - -- Richard Levitte */ - *len_io = password_callback(buf, *len_io, 0, prompt); + if (ui_method) + { + UI *ui = UI_new_method(ui_method); + if (ui) + { + int ok; + char *prompt = UI_construct_prompt(ui, + "pass phrase", prompt_info); + + ok = UI_add_input_string(ui,prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + buf,0,(*len_io) - 1); + UI_add_user_data(ui, callback_data); + if (ok >= 0) + ok=UI_process(ui); + if (ok >= 0) + *len_io = strlen(buf); + + OPENSSL_free(prompt); + UI_free(ui); + } + } + else + { + *len_io = callback(buf, *len_io, 0, callback_data); + } if(!*len_io) return -1; return 0; } +static int hwcrhk_insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext *ppctx, + HWCryptoHook_CallerContext *cactx) + { + int ok = -1; + UI *ui; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; + + if (cactx) + { + if (cactx->ui_method) + ui_method = cactx->ui_method; + if (cactx->callback_data) + callback_data = cactx->callback_data; + } + if (ppctx) + { + if (ppctx->ui_method) + ui_method = ppctx->ui_method; + if (ppctx->callback_data) + callback_data = ppctx->callback_data; + } + if (ui_method == NULL) + { + ENGINEerr(ENGINE_F_HWCRHK_INSERT_CARD,ENGINE_R_NO_CALLBACK); + return -1; + } + + ui = UI_new_method(ui_method); + + if (ui) + { + char answer[10]; + char buf[BUFSIZ]; + + if (wrong_info) + BIO_snprintf(buf, sizeof(buf)-1, + "Current card: \"%s\"\n", wrong_info); + ok = UI_dup_info_string(ui, buf); + if (ok >= 0 && prompt_info) + { + BIO_snprintf(buf, sizeof(buf)-1, + "Insert card \"%s\"\n then hit or C to cancel\n", prompt_info); + ok = UI_dup_input_string(ui, buf, 1, + answer, 0, sizeof(answer)-1); + } + UI_add_user_data(ui, callback_data); + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + /* If canceled input treat as 'cancel' */ + if (ok == -2) + ok = 1; + else if(ok < 0) + ok = -1; + else if (answer[0] == 'c' || answer[0] == 'C') + ok = 1; + else + ok = 0; + } + return ok; + } + static void hwcrhk_log_message(void *logstr, const char *message) { BIO *lstream = NULL;