X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fengine%2Fhw_ncipher.c;h=408db08b9849a28c94578f4759dc68ab1db8cc9c;hp=2879a10a68699f29b9b6fa83c10bf505975f44bf;hb=2b67158673cc0bcedd201b94728269fd5e861fe4;hpb=397211323cb5c631af09f302290b47c5cd441993 diff --git a/crypto/engine/hw_ncipher.c b/crypto/engine/hw_ncipher.c index 2879a10a68..408db08b98 100644 --- a/crypto/engine/hw_ncipher.c +++ b/crypto/engine/hw_ncipher.c @@ -4,7 +4,7 @@ * for the OpenSSL project 2000. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -64,6 +64,7 @@ #include "cryptlib.h" #include #include +#include #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW_NCIPHER @@ -82,6 +83,7 @@ #include "vendor_defns/hwcryptohook.h" #endif +static int hwcrhk_destroy(ENGINE *e); 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)()); @@ -116,13 +118,17 @@ static int hwcrhk_rand_status(void); /* KM stuff */ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, - pem_password_cb *callback, void *callback_data); + UI_METHOD *ui_method, void *callback_data); static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, - pem_password_cb *callback, void *callback_data); + 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, @@ -133,6 +139,8 @@ static void hwcrhk_log_message(void *logstr, const char *message); #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", @@ -146,6 +154,14 @@ static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = { "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} }; @@ -195,6 +211,91 @@ static RAND_METHOD hwcrhk_rand = hwcrhk_rand_status, }; +#ifndef OPENSSL_NO_ERR +/* Error function codes for use in hwcrhk operation */ +#define HWCRHK_F_HWCRHK_INIT 100 +#define HWCRHK_F_HWCRHK_FINISH 101 +#define HWCRHK_F_HWCRHK_CTRL 102 +#define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 103 +#define HWCRHK_F_HWCRHK_LOAD_PUBKEY 104 +#define HWCRHK_F_HWCRHK_MOD_EXP 105 +#define HWCRHK_F_HWCRHK_RSA_MOD_EXP 106 +#define HWCRHK_F_HWCRHK_RAND_BYTES 107 +#define HWCRHK_F_HWCRHK_GET_PASS 108 +#define HWCRHK_F_HWCRHK_INSERT_CARD 109 +/* Error reason codes */ +#define HWCRHK_R_ALREADY_LOADED 110 +#define HWCRHK_R_DSO_FAILURE 111 +#define HWCRHK_R_UNIT_FAILURE 112 +#define HWCRHK_R_NOT_LOADED 113 +#define HWCRHK_R_BIO_WAS_FREED 114 +#define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 115 +#define HWCRHK_R_NOT_INITIALISED 116 +#define HWCRHK_R_CHIL_ERROR 117 +#define HWCRHK_R_NO_KEY 118 +#define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 119 +#define HWCRHK_R_REQUEST_FALLBACK 120 +#define HWCRHK_R_REQUEST_FAILED 121 +#define HWCRHK_R_MISSING_KEY_COMPONENTS 122 +#define HWCRHK_R_NO_CALLBACK 123 +static ERR_STRING_DATA hwcrhk_str_functs[] = + { + /* This first element is changed to match the dynamic 'lib' number */ +{ERR_PACK(0,0,0), "hwcrhk engine code"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_INIT,0), "hwcrhk_init"}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_FINISH,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_CTRL,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PRIVKEY,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_LOAD_PUBKEY,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_MOD_EXP,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_RSA_MOD_EXP,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_RAND_BYTES,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_GET_PASS,0), ""}, +{ERR_PACK(0,HWCRHK_F_HWCRHK_INSERT_CARD,0), ""}, +/* Error reason codes */ +{HWCRHK_R_ALREADY_LOADED ,"already loaded"}, +{HWCRHK_R_DSO_FAILURE ,"DSO failure"}, +{HWCRHK_R_UNIT_FAILURE ,"unit failure"}, +{HWCRHK_R_NOT_LOADED ,"not loaded"}, +{HWCRHK_R_BIO_WAS_FREED ,"BIO was freed"}, +{HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, +{HWCRHK_R_NOT_INITIALISED ,"not initialised"}, +{HWCRHK_R_CHIL_ERROR ,"'chil' error"}, +{HWCRHK_R_NO_KEY ,"no key"}, +{HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED,"private key algorithms disabled"}, +{HWCRHK_R_REQUEST_FALLBACK ,"request fallback"}, +{HWCRHK_R_REQUEST_FAILED ,"request failed"}, +{HWCRHK_R_MISSING_KEY_COMPONENTS ,"missing key components"}, +{HWCRHK_R_NO_CALLBACK ,"no callback"}, +{0,NULL} + }; +/* The library number we obtain dynamically from the ERR code */ +static int hwcrhk_err_lib = -1; +#define HWCRHKerr(f,r) ERR_PUT_error(hwcrhk_err_lib,(f),(r),__FILE__,__LINE__) +static void hwcrhk_load_error_strings(void) + { + if(hwcrhk_err_lib < 0) + { + if((hwcrhk_err_lib = ERR_get_next_error_library()) <= 0) + return; + hwcrhk_str_functs[0].error = ERR_PACK(hwcrhk_err_lib,0,0); + ERR_load_strings(hwcrhk_err_lib, hwcrhk_str_functs); + } + } +static void hwcrhk_unload_error_strings(void) + { + if(hwcrhk_err_lib >= 0) + { + ERR_unload_strings(hwcrhk_err_lib, hwcrhk_str_functs); + hwcrhk_err_lib = -1; + } + } +#else +#define HWCRHKerr(f,r) /* NOP */ +static void hwcrhk_load_error_strings(void) { } /* NOP */ +static void hwcrhk_unload_error_strings(void) { } /* NOP */ +#endif + /* Constants used when creating the ENGINE */ static const char *engine_hwcrhk_id = "chil"; static const char *engine_hwcrhk_name = "nCipher hardware engine support"; @@ -214,7 +315,7 @@ struct HWCryptoHook_MutexValue into HWCryptoHook_PassphraseContext */ struct HWCryptoHook_PassphraseContextValue { - pem_password_cb *password_callback; /* If != NULL, will be called */ + UI_METHOD *ui_method; void *callback_data; }; @@ -223,7 +324,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 @@ -233,28 +337,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 */ @@ -291,16 +391,16 @@ 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 */ }; /* Now, to our own code */ -/* 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_ncipher() +/* This internal function is used by ENGINE_ncipher() and possibly by the + * "dynamic" ENGINE support too */ +static int bind_helper(ENGINE *e) { #ifndef OPENSSL_NO_RSA const RSA_METHOD *meth1; @@ -308,29 +408,24 @@ ENGINE *ENGINE_ncipher() #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) || + if(!ENGINE_set_id(e, engine_hwcrhk_id) || + !ENGINE_set_name(e, engine_hwcrhk_name) || #ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(ret, &hwcrhk_rsa) || + !ENGINE_set_RSA(e, &hwcrhk_rsa) || #endif #ifndef OPENSSL_NO_DH - !ENGINE_set_DH(ret, &hwcrhk_dh) || + !ENGINE_set_DH(e, &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; - } + !ENGINE_set_RAND(e, &hwcrhk_rand) || + !ENGINE_set_BN_mod_exp(e, hwcrhk_mod_exp) || + !ENGINE_set_destroy_function(e, hwcrhk_destroy) || + !ENGINE_set_init_function(e, hwcrhk_init) || + !ENGINE_set_finish_function(e, hwcrhk_finish) || + !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) || + !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) || + !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) || + !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns)) + return 0; #ifndef OPENSSL_NO_RSA /* We know that the "PKCS1_SSLeay()" functions hook properly @@ -353,6 +448,24 @@ ENGINE *ENGINE_ncipher() hwcrhk_dh.generate_key = meth2->generate_key; hwcrhk_dh.compute_key = meth2->compute_key; #endif + + /* Ensure the hwcrhk error handling is set up */ + hwcrhk_load_error_strings(); + return 1; + } + +/* 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_ncipher(void) + { + ENGINE *ret = ENGINE_new(); + if(!ret) + return NULL; + if(!bind_helper(ret)) + { + ENGINE_free(ret); + return NULL; + } return ret; } @@ -406,7 +519,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; @@ -415,7 +529,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; @@ -427,6 +541,13 @@ static void release_context(HWCryptoHook_ContextHandle hac) p_hwcrhk_Finish(hac); } +/* Destructor (complements the "ENGINE_ncipher()" constructor) */ +static int hwcrhk_destroy(ENGINE *e) + { + hwcrhk_unload_error_strings(); + return 1; + } + /* (de)initialisation functions. */ static int hwcrhk_init(ENGINE *e) { @@ -444,14 +565,14 @@ static int hwcrhk_init(ENGINE *e) if(hwcrhk_dso != NULL) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED); goto err; } /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 0); if(hwcrhk_dso == NULL) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } if(!(p1 = (HWCryptoHook_Init_t *) @@ -475,7 +596,7 @@ static int hwcrhk_init(ENGINE *e) !(p9 = (HWCryptoHook_ModExpCRT_t *) DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) { - ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE); goto err; } /* Copy the pointers */ @@ -506,9 +627,9 @@ static int hwcrhk_init(ENGINE *e) /* 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); + HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE); goto err; } /* Everything's fine. */ @@ -542,14 +663,14 @@ static int hwcrhk_finish(ENGINE *e) int to_return = 1; if(hwcrhk_dso == NULL) { - ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED); + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED); to_return = 0; goto err; } release_context(hwcrhk_context); if(!DSO_free(hwcrhk_dso)) { - ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE); + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE); to_return = 0; goto err; } @@ -580,12 +701,12 @@ static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) case HWCRHK_CMD_SO_PATH: if(hwcrhk_dso) { - ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_ALREADY_LOADED); + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED); return 0; } if(p == NULL) { - ENGINEerr(ENGINE_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER); + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER); return 0; } HWCRHK_LIBNAME = (const char *)p; @@ -603,13 +724,23 @@ static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) logstream = bio; else - ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED); + 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_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 @@ -643,8 +774,8 @@ static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) /* The command isn't understood by this engine */ default: - ENGINEerr(ENGINE_F_HWCRHK_CTRL, - ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); to_return = 0; break; } @@ -653,7 +784,7 @@ static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) } static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, - pem_password_cb *callback, void *callback_data) + UI_METHOD *ui_method, void *callback_data) { #ifndef OPENSSL_NO_RSA RSA *rtmp = NULL; @@ -670,32 +801,32 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, - ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_NOT_INITIALISED); goto err; } #ifndef OPENSSL_NO_RSA hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); if (!hptr) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); goto err; } - ppctx.password_callback = callback; + ppctx.ui_method = ui_method; ppctx.callback_data = callback_data; if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, - ENGINE_R_CHIL_ERROR); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } if (!*hptr) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, - ENGINE_R_NO_KEY); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_NO_KEY); goto err; } #endif @@ -710,7 +841,7 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) != HWCRYPTOHOOK_ERROR_MPISIZE) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } @@ -722,8 +853,8 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, - ENGINE_R_CHIL_ERROR); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_CHIL_ERROR); ERR_add_error_data(1,rmsg.buf); goto err; } @@ -737,8 +868,8 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, #endif if (!res) - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, - ENGINE_R_PRIVATE_KEY_ALGORITHMS_DISABLED); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); return res; err: @@ -752,12 +883,13 @@ static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, } static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, - pem_password_cb *callback, void *callback_data) + UI_METHOD *ui_method, void *callback_data) { EVP_PKEY *res = NULL; #ifndef OPENSSL_NO_RSA - res = hwcrhk_load_privkey(eng, key_id, callback, callback_data); + res = hwcrhk_load_privkey(eng, key_id, + ui_method, callback_data); #endif if (res) @@ -778,8 +910,8 @@ static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, } #endif default: - ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, - ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); goto err; } @@ -808,7 +940,7 @@ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED); goto err; } /* Prepare the params */ @@ -832,11 +964,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -857,7 +989,7 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED); goto err; } @@ -871,8 +1003,8 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) if(!rsa->n) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, - ENGINE_R_MISSING_KEY_COMPONENTS); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); goto err; } @@ -898,11 +1030,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -914,8 +1048,8 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, - ENGINE_R_MISSING_KEY_COMPONENTS); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); goto err; } @@ -947,11 +1081,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa) might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -992,7 +1128,7 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num) if(!hwcrhk_context) { - ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED); goto err; } @@ -1004,11 +1140,13 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num) might be a good thing. */ if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, + HWCRHK_R_REQUEST_FALLBACK); } else { - ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED); + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, + HWCRHK_R_REQUEST_FAILED); } ERR_add_error_data(1,rmsg.buf); goto err; @@ -1084,28 +1222,139 @@ static int hwcrhk_get_pass(const char *prompt_info, HWCryptoHook_PassphraseContext *ppctx, HWCryptoHook_CallerContext *cactx) { - pem_password_cb *callback = password_callback; + 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) { - if (ppctx->password_callback) - callback = ppctx->password_callback; + if (ppctx->ui_method) + { + ui_method = ppctx->ui_method; + callback = NULL; + } if (ppctx->callback_data) callback_data = ppctx->callback_data; } - if (callback == NULL) + if (callback == NULL && ui_method == NULL) { - ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); + HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK); return -1; } - *len_io = callback(buf, *len_io, 0, callback_data); + 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); + UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); + + if (ok >= 0) + do + { + ok=UI_process(ui); + } + while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + + if (ok >= 0) + *len_io = strlen(buf); + + UI_free(ui); + OPENSSL_free(prompt); + } + } + 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) + { + HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD, + HWCRHK_R_NO_CALLBACK); + return -1; + } + + ui = UI_new_method(ui_method); + + if (ui) + { + char answer; + 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\"", prompt_info); + ok = UI_dup_input_boolean(ui, buf, + "\n then hit or C to cancel\n", + "\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer); + } + UI_add_user_data(ui, callback_data); + + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + + if (ok == -2 || (ok >= 0 && answer == 'C')) + ok = 1; + else if (ok < 0) + ok = -1; + else + ok = 0; + } + return ok; + } + static void hwcrhk_log_message(void *logstr, const char *message) { BIO *lstream = NULL; @@ -1120,5 +1369,20 @@ static void hwcrhk_log_message(void *logstr, const char *message) CRYPTO_w_unlock(CRYPTO_LOCK_BIO); } +/* This stuff is needed if this ENGINE is being compiled into a self-contained + * shared-library. */ +#ifdef ENGINE_DYNAMIC_SUPPORT +static int bind_fn(ENGINE *e, const char *id) + { + if(id && (strcmp(id, engine_hwcrhk_id) != 0)) + return 0; + if(!bind_helper(e)) + return 0; + return 1; + } +IMPLEMENT_DYNAMIC_CHECK_FN() +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +#endif /* ENGINE_DYNAMIC_SUPPORT */ + #endif /* !OPENSSL_NO_HW_NCIPHER */ #endif /* !OPENSSL_NO_HW */