summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/hw_ncipher.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/hw_ncipher.c')
-rw-r--r--src/lib/libcrypto/engine/hw_ncipher.c662
1 files changed, 482 insertions, 180 deletions
diff --git a/src/lib/libcrypto/engine/hw_ncipher.c b/src/lib/libcrypto/engine/hw_ncipher.c
index 41f5900676..4762a54e3d 100644
--- a/src/lib/libcrypto/engine/hw_ncipher.c
+++ b/src/lib/libcrypto/engine/hw_ncipher.c
@@ -4,7 +4,7 @@
4 * for the OpenSSL project 2000. 4 * for the OpenSSL project 2000.
5 */ 5 */
6/* ==================================================================== 6/* ====================================================================
7 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 7 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
@@ -58,15 +58,16 @@
58 */ 58 */
59 59
60#include <stdio.h> 60#include <stdio.h>
61#include <string.h>
61#include <openssl/crypto.h> 62#include <openssl/crypto.h>
62#include <openssl/pem.h> 63#include <openssl/pem.h>
63#include "cryptlib.h" 64#include "cryptlib.h"
64#include <openssl/dso.h> 65#include <openssl/dso.h>
65#include "engine_int.h"
66#include <openssl/engine.h> 66#include <openssl/engine.h>
67#include <openssl/ui.h>
67 68
68#ifndef NO_HW 69#ifndef OPENSSL_NO_HW
69#ifndef NO_HW_NCIPHER 70#ifndef OPENSSL_NO_HW_NCIPHER
70 71
71/* Attribution notice: nCipher have said several times that it's OK for 72/* Attribution notice: nCipher have said several times that it's OK for
72 * us to implement a general interface to their boxes, and recently declared 73 * us to implement a general interface to their boxes, and recently declared
@@ -82,9 +83,13 @@
82#include "vendor_defns/hwcryptohook.h" 83#include "vendor_defns/hwcryptohook.h"
83#endif 84#endif
84 85
85static int hwcrhk_init(void); 86#define HWCRHK_LIB_NAME "hwcrhk engine"
86static int hwcrhk_finish(void); 87#include "hw_ncipher_err.c"
87static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()); 88
89static int hwcrhk_destroy(ENGINE *e);
90static int hwcrhk_init(ENGINE *e);
91static int hwcrhk_finish(ENGINE *e);
92static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
88 93
89/* Functions to handle mutexes */ 94/* Functions to handle mutexes */
90static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*); 95static int hwcrhk_mutex_init(HWCryptoHook_Mutex*, HWCryptoHook_CallerContext*);
@@ -93,39 +98,77 @@ static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex*);
93static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*); 98static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex*);
94 99
95/* BIGNUM stuff */ 100/* BIGNUM stuff */
96static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 101static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
97 const BIGNUM *m, BN_CTX *ctx); 102 const BIGNUM *m, BN_CTX *ctx);
98 103
104#ifndef OPENSSL_NO_RSA
99/* RSA stuff */ 105/* RSA stuff */
100static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa); 106static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa);
107#endif
101/* This function is aliased to mod_exp (with the mont stuff dropped). */ 108/* This function is aliased to mod_exp (with the mont stuff dropped). */
102static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 109static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
103 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 110 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
104 111
105/* DH stuff */ 112/* DH stuff */
106/* This function is alised to mod_exp (with the DH and mont dropped). */ 113/* This function is alised to mod_exp (with the DH and mont dropped). */
107static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 114static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
108 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); 115 const BIGNUM *a, const BIGNUM *p,
116 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
109 117
110/* RAND stuff */ 118/* RAND stuff */
111static int hwcrhk_rand_bytes(unsigned char *buf, int num); 119static int hwcrhk_rand_bytes(unsigned char *buf, int num);
112static int hwcrhk_rand_status(void); 120static int hwcrhk_rand_status(void);
113 121
114/* KM stuff */ 122/* KM stuff */
115static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, 123static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
116 const char *passphrase); 124 UI_METHOD *ui_method, void *callback_data);
117static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, 125static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
118 const char *passphrase); 126 UI_METHOD *ui_method, void *callback_data);
119static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 127static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
120 int index,long argl, void *argp); 128 int ind,long argl, void *argp);
121 129
122/* Interaction stuff */ 130/* Interaction stuff */
131static int hwcrhk_insert_card(const char *prompt_info,
132 const char *wrong_info,
133 HWCryptoHook_PassphraseContext *ppctx,
134 HWCryptoHook_CallerContext *cactx);
123static int hwcrhk_get_pass(const char *prompt_info, 135static int hwcrhk_get_pass(const char *prompt_info,
124 int *len_io, char *buf, 136 int *len_io, char *buf,
125 HWCryptoHook_PassphraseContext *ppctx, 137 HWCryptoHook_PassphraseContext *ppctx,
126 HWCryptoHook_CallerContext *cactx); 138 HWCryptoHook_CallerContext *cactx);
127static void hwcrhk_log_message(void *logstream, const char *message); 139static void hwcrhk_log_message(void *logstr, const char *message);
140
141/* The definitions for control commands specific to this engine */
142#define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE
143#define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1)
144#define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2)
145#define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3)
146#define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4)
147static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = {
148 {HWCRHK_CMD_SO_PATH,
149 "SO_PATH",
150 "Specifies the path to the 'hwcrhk' shared library",
151 ENGINE_CMD_FLAG_STRING},
152 {HWCRHK_CMD_FORK_CHECK,
153 "FORK_CHECK",
154 "Turns fork() checking on or off (boolean)",
155 ENGINE_CMD_FLAG_NUMERIC},
156 {HWCRHK_CMD_THREAD_LOCKING,
157 "THREAD_LOCKING",
158 "Turns thread-safe locking on or off (boolean)",
159 ENGINE_CMD_FLAG_NUMERIC},
160 {HWCRHK_CMD_SET_USER_INTERFACE,
161 "SET_USER_INTERFACE",
162 "Set the global user interface (internal)",
163 ENGINE_CMD_FLAG_INTERNAL},
164 {HWCRHK_CMD_SET_CALLBACK_DATA,
165 "SET_CALLBACK_DATA",
166 "Set the global user interface extra data (internal)",
167 ENGINE_CMD_FLAG_INTERNAL},
168 {0, NULL, NULL, 0}
169 };
128 170
171#ifndef OPENSSL_NO_RSA
129/* Our internal RSA_METHOD that we provide pointers to */ 172/* Our internal RSA_METHOD that we provide pointers to */
130static RSA_METHOD hwcrhk_rsa = 173static RSA_METHOD hwcrhk_rsa =
131 { 174 {
@@ -143,7 +186,9 @@ static RSA_METHOD hwcrhk_rsa =
143 NULL, 186 NULL,
144 NULL 187 NULL
145 }; 188 };
189#endif
146 190
191#ifndef OPENSSL_NO_DH
147/* Our internal DH_METHOD that we provide pointers to */ 192/* Our internal DH_METHOD that we provide pointers to */
148static DH_METHOD hwcrhk_dh = 193static DH_METHOD hwcrhk_dh =
149 { 194 {
@@ -156,6 +201,7 @@ static DH_METHOD hwcrhk_dh =
156 0, 201 0,
157 NULL 202 NULL
158 }; 203 };
204#endif
159 205
160static RAND_METHOD hwcrhk_rand = 206static RAND_METHOD hwcrhk_rand =
161 { 207 {
@@ -168,26 +214,9 @@ static RAND_METHOD hwcrhk_rand =
168 hwcrhk_rand_status, 214 hwcrhk_rand_status,
169 }; 215 };
170 216
171/* Our ENGINE structure. */ 217/* Constants used when creating the ENGINE */
172static ENGINE engine_hwcrhk = 218static const char *engine_hwcrhk_id = "chil";
173 { 219static const char *engine_hwcrhk_name = "nCipher hardware engine support";
174 "chil",
175 "nCipher hardware engine support",
176 &hwcrhk_rsa,
177 NULL,
178 &hwcrhk_dh,
179 &hwcrhk_rand,
180 hwcrhk_mod_exp,
181 NULL,
182 hwcrhk_init,
183 hwcrhk_finish,
184 hwcrhk_ctrl,
185 hwcrhk_load_privkey,
186 hwcrhk_load_pubkey,
187 0, /* no flags */
188 0, 0, /* no references */
189 NULL, NULL /* unlinked */
190 };
191 220
192/* Internal stuff for HWCryptoHook */ 221/* Internal stuff for HWCryptoHook */
193 222
@@ -204,7 +233,8 @@ struct HWCryptoHook_MutexValue
204 into HWCryptoHook_PassphraseContext */ 233 into HWCryptoHook_PassphraseContext */
205struct HWCryptoHook_PassphraseContextValue 234struct HWCryptoHook_PassphraseContextValue
206 { 235 {
207 void *any; 236 UI_METHOD *ui_method;
237 void *callback_data;
208 }; 238 };
209 239
210/* hwcryptohook.h has some typedefs that turn 240/* hwcryptohook.h has some typedefs that turn
@@ -212,7 +242,10 @@ struct HWCryptoHook_PassphraseContextValue
212 into HWCryptoHook_CallerContext */ 242 into HWCryptoHook_CallerContext */
213struct HWCryptoHook_CallerContextValue 243struct HWCryptoHook_CallerContextValue
214 { 244 {
215 void *any; 245 pem_password_cb *password_callback; /* Deprecated! Only present for
246 backward compatibility! */
247 UI_METHOD *ui_method;
248 void *callback_data;
216 }; 249 };
217 250
218/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL 251/* The MPI structure in HWCryptoHook is pretty compatible with OpenSSL
@@ -222,31 +255,27 @@ struct HWCryptoHook_CallerContextValue
222#define MPI2BN(bn, mp) \ 255#define MPI2BN(bn, mp) \
223 {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} 256 {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;}
224 257
225#if 0 /* Card and password management is not yet supported */
226/* HWCryptoHook callbacks. insert_card() and get_pass() are not yet
227 defined, because we haven't quite decided on the proper form yet.
228 log_message() just adds an entry in the error stack. I don't know
229 if that's good or bad... */
230static int insert_card(const char *prompt_info,
231 const char *wrong_info,
232 HWCryptoHook_PassphraseContext *ppctx,
233 HWCryptoHook_CallerContext *cactx);
234static int get_pass(const char *prompt_info,
235 int *len_io, char *buf,
236 HWCryptoHook_PassphraseContext *ppctx,
237 HWCryptoHook_CallerContext *cactx);
238#endif
239
240static BIO *logstream = NULL; 258static BIO *logstream = NULL;
241static pem_password_cb *password_callback = NULL;
242#if 0
243static void *password_callback_userdata = NULL;
244#endif
245static int disable_mutex_callbacks = 0; 259static int disable_mutex_callbacks = 0;
246 260
261/* One might wonder why these are needed, since one can pass down at least
262 a UI_METHOD and a pointer to callback data to the key-loading functions.
263 The thing is that the ModExp and RSAImmed functions can load keys as well,
264 if the data they get is in a special, nCipher-defined format (hint: if you
265 look at the private exponent of the RSA data as a string, you'll see this
266 string: "nCipher KM tool key id", followed by some bytes, followed a key
267 identity string, followed by more bytes. This happens when you use "embed"
268 keys instead of "hwcrhk" keys). Unfortunately, those functions do not take
269 any passphrase or caller context, and our functions can't really take any
270 callback data either. Still, the "insert_card" and "get_passphrase"
271 callbacks may be called down the line, and will need to know what user
272 interface callbacks to call, and having callback data from the application
273 may be a nice thing as well, so we need to keep track of that globally. */
274static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL };
275
247/* Stuff to pass to the HWCryptoHook library */ 276/* Stuff to pass to the HWCryptoHook library */
248static HWCryptoHook_InitInfo hwcrhk_globals = { 277static HWCryptoHook_InitInfo hwcrhk_globals = {
249 0, /* Flags */ 278 HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */
250 &logstream, /* logstream */ 279 &logstream, /* logstream */
251 sizeof(BN_ULONG), /* limbsize */ 280 sizeof(BN_ULONG), /* limbsize */
252 0, /* mslimb first: false for BNs */ 281 0, /* mslimb first: false for BNs */
@@ -280,20 +309,42 @@ static HWCryptoHook_InitInfo hwcrhk_globals = {
280 0, /* hwcrhk_cv_destroy, */ 309 0, /* hwcrhk_cv_destroy, */
281 310
282 hwcrhk_get_pass, /* pass phrase */ 311 hwcrhk_get_pass, /* pass phrase */
283 0, /* insert_card, */ /* insert a card */ 312 hwcrhk_insert_card, /* insert a card */
284 hwcrhk_log_message /* Log message */ 313 hwcrhk_log_message /* Log message */
285}; 314};
286 315
287 316
288/* Now, to our own code */ 317/* Now, to our own code */
289 318
290/* As this is only ever called once, there's no need for locking 319/* This internal function is used by ENGINE_ncipher() and possibly by the
291 * (indeed - the lock will already be held by our caller!!!) */ 320 * "dynamic" ENGINE support too */
292ENGINE *ENGINE_ncipher() 321static int bind_helper(ENGINE *e)
293 { 322 {
294 RSA_METHOD *meth1; 323#ifndef OPENSSL_NO_RSA
295 DH_METHOD *meth2; 324 const RSA_METHOD *meth1;
325#endif
326#ifndef OPENSSL_NO_DH
327 const DH_METHOD *meth2;
328#endif
329 if(!ENGINE_set_id(e, engine_hwcrhk_id) ||
330 !ENGINE_set_name(e, engine_hwcrhk_name) ||
331#ifndef OPENSSL_NO_RSA
332 !ENGINE_set_RSA(e, &hwcrhk_rsa) ||
333#endif
334#ifndef OPENSSL_NO_DH
335 !ENGINE_set_DH(e, &hwcrhk_dh) ||
336#endif
337 !ENGINE_set_RAND(e, &hwcrhk_rand) ||
338 !ENGINE_set_destroy_function(e, hwcrhk_destroy) ||
339 !ENGINE_set_init_function(e, hwcrhk_init) ||
340 !ENGINE_set_finish_function(e, hwcrhk_finish) ||
341 !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) ||
342 !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) ||
343 !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) ||
344 !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns))
345 return 0;
296 346
347#ifndef OPENSSL_NO_RSA
297 /* We know that the "PKCS1_SSLeay()" functions hook properly 348 /* We know that the "PKCS1_SSLeay()" functions hook properly
298 * to the cswift-specific mod_exp and mod_exp_crt so we use 349 * to the cswift-specific mod_exp and mod_exp_crt so we use
299 * those functions. NB: We don't use ENGINE_openssl() or 350 * those functions. NB: We don't use ENGINE_openssl() or
@@ -306,12 +357,41 @@ ENGINE *ENGINE_ncipher()
306 hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; 357 hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec;
307 hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; 358 hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc;
308 hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; 359 hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec;
360#endif
309 361
362#ifndef OPENSSL_NO_DH
310 /* Much the same for Diffie-Hellman */ 363 /* Much the same for Diffie-Hellman */
311 meth2 = DH_OpenSSL(); 364 meth2 = DH_OpenSSL();
312 hwcrhk_dh.generate_key = meth2->generate_key; 365 hwcrhk_dh.generate_key = meth2->generate_key;
313 hwcrhk_dh.compute_key = meth2->compute_key; 366 hwcrhk_dh.compute_key = meth2->compute_key;
314 return &engine_hwcrhk; 367#endif
368
369 /* Ensure the hwcrhk error handling is set up */
370 ERR_load_HWCRHK_strings();
371 return 1;
372 }
373
374static ENGINE *engine_ncipher(void)
375 {
376 ENGINE *ret = ENGINE_new();
377 if(!ret)
378 return NULL;
379 if(!bind_helper(ret))
380 {
381 ENGINE_free(ret);
382 return NULL;
383 }
384 return ret;
385 }
386
387void ENGINE_load_chil(void)
388 {
389 /* Copied from eng_[openssl|dyn].c */
390 ENGINE *toadd = engine_ncipher();
391 if(!toadd) return;
392 ENGINE_add(toadd);
393 ENGINE_free(toadd);
394 ERR_clear_error();
315 } 395 }
316 396
317/* This is a process-global DSO handle used for loading and unloading 397/* This is a process-global DSO handle used for loading and unloading
@@ -321,30 +401,41 @@ ENGINE *ENGINE_ncipher()
321 * implicitly. */ 401 * implicitly. */
322static DSO *hwcrhk_dso = NULL; 402static DSO *hwcrhk_dso = NULL;
323static HWCryptoHook_ContextHandle hwcrhk_context = 0; 403static HWCryptoHook_ContextHandle hwcrhk_context = 0;
324static int hndidx = -1; /* Index for KM handle. Not really used yet. */ 404#ifndef OPENSSL_NO_RSA
405static int hndidx_rsa = -1; /* Index for KM handle. Not really used yet. */
406#endif
325 407
326/* These are the function pointers that are (un)set when the library has 408/* These are the function pointers that are (un)set when the library has
327 * successfully (un)loaded. */ 409 * successfully (un)loaded. */
328static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; 410static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL;
329static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; 411static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL;
330static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; 412static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL;
413#ifndef OPENSSL_NO_RSA
331static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; 414static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL;
415#endif
332static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; 416static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL;
417#ifndef OPENSSL_NO_RSA
333static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; 418static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL;
334static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; 419static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL;
335static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; 420static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL;
421#endif
336static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; 422static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL;
337 423
338/* Used in the DSO operations. */ 424/* Used in the DSO operations. */
339static const char *HWCRHK_LIBNAME = "nfhwcrhk"; 425static const char def_HWCRHK_LIBNAME[] = "nfhwcrhk";
426static const char *HWCRHK_LIBNAME = def_HWCRHK_LIBNAME;
340static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; 427static const char *n_hwcrhk_Init = "HWCryptoHook_Init";
341static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; 428static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish";
342static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; 429static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp";
430#ifndef OPENSSL_NO_RSA
343static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; 431static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA";
432#endif
344static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; 433static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes";
434#ifndef OPENSSL_NO_RSA
345static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; 435static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey";
346static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; 436static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey";
347static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; 437static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey";
438#endif
348static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; 439static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
349 440
350/* HWCryptoHook library functions and mechanics - these are used by the 441/* HWCryptoHook library functions and mechanics - these are used by the
@@ -353,16 +444,17 @@ static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT";
353 * called, the checking and error handling is probably down there. */ 444 * called, the checking and error handling is probably down there. */
354 445
355/* utility function to obtain a context */ 446/* utility function to obtain a context */
356static int get_context(HWCryptoHook_ContextHandle *hac) 447static int get_context(HWCryptoHook_ContextHandle *hac,
448 HWCryptoHook_CallerContext *cac)
357 { 449 {
358 char tempbuf[1024]; 450 char tempbuf[1024];
359 HWCryptoHook_ErrMsgBuf rmsg; 451 HWCryptoHook_ErrMsgBuf rmsg;
360 452
361 rmsg.buf = tempbuf; 453 rmsg.buf = tempbuf;
362 rmsg.size = 1024; 454 rmsg.size = sizeof(tempbuf);
363 455
364 *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, 456 *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg,
365 NULL); 457 cac);
366 if (!*hac) 458 if (!*hac)
367 return 0; 459 return 0;
368 return 1; 460 return 1;
@@ -374,30 +466,38 @@ static void release_context(HWCryptoHook_ContextHandle hac)
374 p_hwcrhk_Finish(hac); 466 p_hwcrhk_Finish(hac);
375 } 467 }
376 468
469/* Destructor (complements the "ENGINE_ncipher()" constructor) */
470static int hwcrhk_destroy(ENGINE *e)
471 {
472 ERR_unload_HWCRHK_strings();
473 return 1;
474 }
475
377/* (de)initialisation functions. */ 476/* (de)initialisation functions. */
378static int hwcrhk_init() 477static int hwcrhk_init(ENGINE *e)
379 { 478 {
380 HWCryptoHook_Init_t *p1; 479 HWCryptoHook_Init_t *p1;
381 HWCryptoHook_Finish_t *p2; 480 HWCryptoHook_Finish_t *p2;
382 HWCryptoHook_ModExp_t *p3; 481 HWCryptoHook_ModExp_t *p3;
482#ifndef OPENSSL_NO_RSA
383 HWCryptoHook_RSA_t *p4; 483 HWCryptoHook_RSA_t *p4;
384 HWCryptoHook_RSALoadKey_t *p5; 484 HWCryptoHook_RSALoadKey_t *p5;
385 HWCryptoHook_RSAGetPublicKey_t *p6; 485 HWCryptoHook_RSAGetPublicKey_t *p6;
386 HWCryptoHook_RSAUnloadKey_t *p7; 486 HWCryptoHook_RSAUnloadKey_t *p7;
487#endif
387 HWCryptoHook_RandomBytes_t *p8; 488 HWCryptoHook_RandomBytes_t *p8;
388 HWCryptoHook_ModExpCRT_t *p9; 489 HWCryptoHook_ModExpCRT_t *p9;
389 490
390 if(hwcrhk_dso != NULL) 491 if(hwcrhk_dso != NULL)
391 { 492 {
392 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_ALREADY_LOADED); 493 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_ALREADY_LOADED);
393 goto err; 494 goto err;
394 } 495 }
395 /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ 496 /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */
396 hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 497 hwcrhk_dso = DSO_load(NULL, HWCRHK_LIBNAME, NULL, 0);
397 DSO_FLAG_NAME_TRANSLATION);
398 if(hwcrhk_dso == NULL) 498 if(hwcrhk_dso == NULL)
399 { 499 {
400 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); 500 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
401 goto err; 501 goto err;
402 } 502 }
403 if(!(p1 = (HWCryptoHook_Init_t *) 503 if(!(p1 = (HWCryptoHook_Init_t *)
@@ -406,6 +506,7 @@ static int hwcrhk_init()
406 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || 506 DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) ||
407 !(p3 = (HWCryptoHook_ModExp_t *) 507 !(p3 = (HWCryptoHook_ModExp_t *)
408 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || 508 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) ||
509#ifndef OPENSSL_NO_RSA
409 !(p4 = (HWCryptoHook_RSA_t *) 510 !(p4 = (HWCryptoHook_RSA_t *)
410 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || 511 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) ||
411 !(p5 = (HWCryptoHook_RSALoadKey_t *) 512 !(p5 = (HWCryptoHook_RSALoadKey_t *)
@@ -414,22 +515,25 @@ static int hwcrhk_init()
414 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || 515 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) ||
415 !(p7 = (HWCryptoHook_RSAUnloadKey_t *) 516 !(p7 = (HWCryptoHook_RSAUnloadKey_t *)
416 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || 517 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) ||
518#endif
417 !(p8 = (HWCryptoHook_RandomBytes_t *) 519 !(p8 = (HWCryptoHook_RandomBytes_t *)
418 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || 520 DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) ||
419 !(p9 = (HWCryptoHook_ModExpCRT_t *) 521 !(p9 = (HWCryptoHook_ModExpCRT_t *)
420 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) 522 DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT)))
421 { 523 {
422 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_DSO_FAILURE); 524 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_DSO_FAILURE);
423 goto err; 525 goto err;
424 } 526 }
425 /* Copy the pointers */ 527 /* Copy the pointers */
426 p_hwcrhk_Init = p1; 528 p_hwcrhk_Init = p1;
427 p_hwcrhk_Finish = p2; 529 p_hwcrhk_Finish = p2;
428 p_hwcrhk_ModExp = p3; 530 p_hwcrhk_ModExp = p3;
531#ifndef OPENSSL_NO_RSA
429 p_hwcrhk_RSA = p4; 532 p_hwcrhk_RSA = p4;
430 p_hwcrhk_RSALoadKey = p5; 533 p_hwcrhk_RSALoadKey = p5;
431 p_hwcrhk_RSAGetPublicKey = p6; 534 p_hwcrhk_RSAGetPublicKey = p6;
432 p_hwcrhk_RSAUnloadKey = p7; 535 p_hwcrhk_RSAUnloadKey = p7;
536#endif
433 p_hwcrhk_RandomBytes = p8; 537 p_hwcrhk_RandomBytes = p8;
434 p_hwcrhk_ModExpCRT = p9; 538 p_hwcrhk_ModExpCRT = p9;
435 539
@@ -448,16 +552,18 @@ static int hwcrhk_init()
448 552
449 /* Try and get a context - if not, we may have a DSO but no 553 /* Try and get a context - if not, we may have a DSO but no
450 * accelerator! */ 554 * accelerator! */
451 if(!get_context(&hwcrhk_context)) 555 if(!get_context(&hwcrhk_context, &password_context))
452 { 556 {
453 ENGINEerr(ENGINE_F_HWCRHK_INIT,ENGINE_R_UNIT_FAILURE); 557 HWCRHKerr(HWCRHK_F_HWCRHK_INIT,HWCRHK_R_UNIT_FAILURE);
454 goto err; 558 goto err;
455 } 559 }
456 /* Everything's fine. */ 560 /* Everything's fine. */
457 if (hndidx == -1) 561#ifndef OPENSSL_NO_RSA
458 hndidx = RSA_get_ex_new_index(0, 562 if (hndidx_rsa == -1)
563 hndidx_rsa = RSA_get_ex_new_index(0,
459 "nFast HWCryptoHook RSA key handle", 564 "nFast HWCryptoHook RSA key handle",
460 NULL, NULL, hwcrhk_ex_free); 565 NULL, NULL, hwcrhk_ex_free);
566#endif
461 return 1; 567 return 1;
462err: 568err:
463 if(hwcrhk_dso) 569 if(hwcrhk_dso)
@@ -466,28 +572,30 @@ err:
466 p_hwcrhk_Init = NULL; 572 p_hwcrhk_Init = NULL;
467 p_hwcrhk_Finish = NULL; 573 p_hwcrhk_Finish = NULL;
468 p_hwcrhk_ModExp = NULL; 574 p_hwcrhk_ModExp = NULL;
575#ifndef OPENSSL_NO_RSA
469 p_hwcrhk_RSA = NULL; 576 p_hwcrhk_RSA = NULL;
470 p_hwcrhk_RSALoadKey = NULL; 577 p_hwcrhk_RSALoadKey = NULL;
471 p_hwcrhk_RSAGetPublicKey = NULL; 578 p_hwcrhk_RSAGetPublicKey = NULL;
472 p_hwcrhk_RSAUnloadKey = NULL; 579 p_hwcrhk_RSAUnloadKey = NULL;
580#endif
473 p_hwcrhk_ModExpCRT = NULL; 581 p_hwcrhk_ModExpCRT = NULL;
474 p_hwcrhk_RandomBytes = NULL; 582 p_hwcrhk_RandomBytes = NULL;
475 return 0; 583 return 0;
476 } 584 }
477 585
478static int hwcrhk_finish() 586static int hwcrhk_finish(ENGINE *e)
479 { 587 {
480 int to_return = 1; 588 int to_return = 1;
481 if(hwcrhk_dso == NULL) 589 if(hwcrhk_dso == NULL)
482 { 590 {
483 ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_NOT_LOADED); 591 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_NOT_LOADED);
484 to_return = 0; 592 to_return = 0;
485 goto err; 593 goto err;
486 } 594 }
487 release_context(hwcrhk_context); 595 release_context(hwcrhk_context);
488 if(!DSO_free(hwcrhk_dso)) 596 if(!DSO_free(hwcrhk_dso))
489 { 597 {
490 ENGINEerr(ENGINE_F_HWCRHK_FINISH,ENGINE_R_DSO_FAILURE); 598 HWCRHKerr(HWCRHK_F_HWCRHK_FINISH,HWCRHK_R_DSO_FAILURE);
491 to_return = 0; 599 to_return = 0;
492 goto err; 600 goto err;
493 } 601 }
@@ -498,21 +606,36 @@ static int hwcrhk_finish()
498 p_hwcrhk_Init = NULL; 606 p_hwcrhk_Init = NULL;
499 p_hwcrhk_Finish = NULL; 607 p_hwcrhk_Finish = NULL;
500 p_hwcrhk_ModExp = NULL; 608 p_hwcrhk_ModExp = NULL;
609#ifndef OPENSSL_NO_RSA
501 p_hwcrhk_RSA = NULL; 610 p_hwcrhk_RSA = NULL;
502 p_hwcrhk_RSALoadKey = NULL; 611 p_hwcrhk_RSALoadKey = NULL;
503 p_hwcrhk_RSAGetPublicKey = NULL; 612 p_hwcrhk_RSAGetPublicKey = NULL;
504 p_hwcrhk_RSAUnloadKey = NULL; 613 p_hwcrhk_RSAUnloadKey = NULL;
614#endif
505 p_hwcrhk_ModExpCRT = NULL; 615 p_hwcrhk_ModExpCRT = NULL;
506 p_hwcrhk_RandomBytes = NULL; 616 p_hwcrhk_RandomBytes = NULL;
507 return to_return; 617 return to_return;
508 } 618 }
509 619
510static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)()) 620static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
511 { 621 {
512 int to_return = 1; 622 int to_return = 1;
513 623
514 switch(cmd) 624 switch(cmd)
515 { 625 {
626 case HWCRHK_CMD_SO_PATH:
627 if(hwcrhk_dso)
628 {
629 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_ALREADY_LOADED);
630 return 0;
631 }
632 if(p == NULL)
633 {
634 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,ERR_R_PASSED_NULL_PARAMETER);
635 return 0;
636 }
637 HWCRHK_LIBNAME = (const char *)p;
638 return 1;
516 case ENGINE_CTRL_SET_LOGSTREAM: 639 case ENGINE_CTRL_SET_LOGSTREAM:
517 { 640 {
518 BIO *bio = (BIO *)p; 641 BIO *bio = (BIO *)p;
@@ -526,18 +649,31 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
526 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1) 649 if (CRYPTO_add(&bio->references,1,CRYPTO_LOCK_BIO) > 1)
527 logstream = bio; 650 logstream = bio;
528 else 651 else
529 ENGINEerr(ENGINE_F_HWCRHK_CTRL,ENGINE_R_BIO_WAS_FREED); 652 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,HWCRHK_R_BIO_WAS_FREED);
530 } 653 }
531 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 654 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
532 break; 655 break;
533 case ENGINE_CTRL_SET_PASSWORD_CALLBACK: 656 case ENGINE_CTRL_SET_PASSWORD_CALLBACK:
534 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 657 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
535 password_callback = (pem_password_cb *)f; 658 password_context.password_callback = (pem_password_cb *)f;
659 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
660 break;
661 case ENGINE_CTRL_SET_USER_INTERFACE:
662 case HWCRHK_CMD_SET_USER_INTERFACE:
663 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
664 password_context.ui_method = (UI_METHOD *)p;
665 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
666 break;
667 case ENGINE_CTRL_SET_CALLBACK_DATA:
668 case HWCRHK_CMD_SET_CALLBACK_DATA:
669 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
670 password_context.callback_data = p;
536 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 671 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
537 break; 672 break;
538 /* this enables or disables the "SimpleForkCheck" flag used in the 673 /* this enables or disables the "SimpleForkCheck" flag used in the
539 * initialisation structure. */ 674 * initialisation structure. */
540 case ENGINE_CTRL_CHIL_SET_FORKCHECK: 675 case ENGINE_CTRL_CHIL_SET_FORKCHECK:
676 case HWCRHK_CMD_FORK_CHECK:
541 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 677 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
542 if(i) 678 if(i)
543 hwcrhk_globals.flags |= 679 hwcrhk_globals.flags |=
@@ -557,11 +693,16 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
557 disable_mutex_callbacks = 1; 693 disable_mutex_callbacks = 1;
558 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 694 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
559 break; 695 break;
696 case HWCRHK_CMD_THREAD_LOCKING:
697 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
698 disable_mutex_callbacks = ((i == 0) ? 0 : 1);
699 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
700 break;
560 701
561 /* The command isn't understood by this engine */ 702 /* The command isn't understood by this engine */
562 default: 703 default:
563 ENGINEerr(ENGINE_F_HWCRHK_CTRL, 704 HWCRHKerr(HWCRHK_F_HWCRHK_CTRL,
564 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); 705 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
565 to_return = 0; 706 to_return = 0;
566 break; 707 break;
567 } 708 }
@@ -569,44 +710,62 @@ static int hwcrhk_ctrl(int cmd, long i, void *p, void (*f)())
569 return to_return; 710 return to_return;
570 } 711 }
571 712
572static EVP_PKEY *hwcrhk_load_privkey(const char *key_id, 713static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id,
573 const char *passphrase) 714 UI_METHOD *ui_method, void *callback_data)
574 { 715 {
716#ifndef OPENSSL_NO_RSA
575 RSA *rtmp = NULL; 717 RSA *rtmp = NULL;
718#endif
576 EVP_PKEY *res = NULL; 719 EVP_PKEY *res = NULL;
720#ifndef OPENSSL_NO_RSA
577 HWCryptoHook_MPI e, n; 721 HWCryptoHook_MPI e, n;
578 HWCryptoHook_RSAKeyHandle *hptr; 722 HWCryptoHook_RSAKeyHandle *hptr;
723#endif
724#if !defined(OPENSSL_NO_RSA)
725 char tempbuf[1024];
579 HWCryptoHook_ErrMsgBuf rmsg; 726 HWCryptoHook_ErrMsgBuf rmsg;
727#endif
728 HWCryptoHook_PassphraseContext ppctx;
729
730#if !defined(OPENSSL_NO_RSA)
731 rmsg.buf = tempbuf;
732 rmsg.size = sizeof(tempbuf);
733#endif
580 734
581 if(!hwcrhk_context) 735 if(!hwcrhk_context)
582 { 736 {
583 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 737 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
584 ENGINE_R_NOT_INITIALISED); 738 HWCRHK_R_NOT_INITIALISED);
585 goto err; 739 goto err;
586 } 740 }
741#ifndef OPENSSL_NO_RSA
587 hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); 742 hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle));
588 if (!hptr) 743 if (!hptr)
589 { 744 {
590 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 745 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
591 ERR_R_MALLOC_FAILURE); 746 ERR_R_MALLOC_FAILURE);
592 goto err; 747 goto err;
593 } 748 }
749 ppctx.ui_method = ui_method;
750 ppctx.callback_data = callback_data;
594 if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, 751 if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr,
595 &rmsg, NULL)) 752 &rmsg, &ppctx))
596 { 753 {
597 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 754 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
598 ENGINE_R_CHIL_ERROR); 755 HWCRHK_R_CHIL_ERROR);
599 ERR_add_error_data(1,rmsg.buf); 756 ERR_add_error_data(1,rmsg.buf);
600 goto err; 757 goto err;
601 } 758 }
602 if (!*hptr) 759 if (!*hptr)
603 { 760 {
604 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PRIVKEY, 761 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY,
605 ENGINE_R_NO_KEY); 762 HWCRHK_R_NO_KEY);
606 goto err; 763 goto err;
607 } 764 }
608 rtmp = RSA_new_method(&engine_hwcrhk); 765#endif
609 RSA_set_ex_data(rtmp, hndidx, (char *)hptr); 766#ifndef OPENSSL_NO_RSA
767 rtmp = RSA_new_method(eng);
768 RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr);
610 rtmp->e = BN_new(); 769 rtmp->e = BN_new();
611 rtmp->n = BN_new(); 770 rtmp->n = BN_new();
612 rtmp->flags |= RSA_FLAG_EXT_PKEY; 771 rtmp->flags |= RSA_FLAG_EXT_PKEY;
@@ -615,11 +774,11 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
615 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) 774 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)
616 != HWCRYPTOHOOK_ERROR_MPISIZE) 775 != HWCRYPTOHOOK_ERROR_MPISIZE)
617 { 776 {
618 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY,ENGINE_R_CHIL_ERROR); 777 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,HWCRHK_R_CHIL_ERROR);
619 ERR_add_error_data(1,rmsg.buf); 778 ERR_add_error_data(1,rmsg.buf);
620 goto err; 779 goto err;
621 } 780 }
622 781
623 bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG)); 782 bn_expand2(rtmp->e, e.size/sizeof(BN_ULONG));
624 bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG)); 783 bn_expand2(rtmp->n, n.size/sizeof(BN_ULONG));
625 MPI2BN(rtmp->e, e); 784 MPI2BN(rtmp->e, e);
@@ -627,8 +786,8 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
627 786
628 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) 787 if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg))
629 { 788 {
630 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, 789 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
631 ENGINE_R_CHIL_ERROR); 790 HWCRHK_R_CHIL_ERROR);
632 ERR_add_error_data(1,rmsg.buf); 791 ERR_add_error_data(1,rmsg.buf);
633 goto err; 792 goto err;
634 } 793 }
@@ -639,23 +798,37 @@ static EVP_PKEY *hwcrhk_load_privkey(const char *key_id,
639 798
640 res = EVP_PKEY_new(); 799 res = EVP_PKEY_new();
641 EVP_PKEY_assign_RSA(res, rtmp); 800 EVP_PKEY_assign_RSA(res, rtmp);
801#endif
802
803 if (!res)
804 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
805 HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED);
642 806
643 return res; 807 return res;
644 err: 808 err:
645 if (res) 809 if (res)
646 EVP_PKEY_free(res); 810 EVP_PKEY_free(res);
811#ifndef OPENSSL_NO_RSA
647 if (rtmp) 812 if (rtmp)
648 RSA_free(rtmp); 813 RSA_free(rtmp);
814#endif
649 return NULL; 815 return NULL;
650 } 816 }
651 817
652static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase) 818static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id,
819 UI_METHOD *ui_method, void *callback_data)
653 { 820 {
654 EVP_PKEY *res = hwcrhk_load_privkey(key_id, passphrase); 821 EVP_PKEY *res = NULL;
822
823#ifndef OPENSSL_NO_RSA
824 res = hwcrhk_load_privkey(eng, key_id,
825 ui_method, callback_data);
826#endif
655 827
656 if (res) 828 if (res)
657 switch(res->type) 829 switch(res->type)
658 { 830 {
831#ifndef OPENSSL_NO_RSA
659 case EVP_PKEY_RSA: 832 case EVP_PKEY_RSA:
660 { 833 {
661 RSA *rsa = NULL; 834 RSA *rsa = NULL;
@@ -665,12 +838,16 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
665 res->pkey.rsa = RSA_new(); 838 res->pkey.rsa = RSA_new();
666 res->pkey.rsa->n = rsa->n; 839 res->pkey.rsa->n = rsa->n;
667 res->pkey.rsa->e = rsa->e; 840 res->pkey.rsa->e = rsa->e;
841 rsa->n = NULL;
842 rsa->e = NULL;
668 CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); 843 CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
669 RSA_free(rsa); 844 RSA_free(rsa);
670 } 845 }
846 break;
847#endif
671 default: 848 default:
672 ENGINEerr(ENGINE_F_HWCRHK_LOAD_PUBKEY, 849 HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY,
673 ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); 850 HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED);
674 goto err; 851 goto err;
675 } 852 }
676 853
@@ -682,7 +859,7 @@ static EVP_PKEY *hwcrhk_load_pubkey(const char *key_id, const char *passphrase)
682 } 859 }
683 860
684/* A little mod_exp */ 861/* A little mod_exp */
685static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 862static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
686 const BIGNUM *m, BN_CTX *ctx) 863 const BIGNUM *m, BN_CTX *ctx)
687 { 864 {
688 char tempbuf[1024]; 865 char tempbuf[1024];
@@ -695,11 +872,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
695 872
696 to_return = 0; /* expect failure */ 873 to_return = 0; /* expect failure */
697 rmsg.buf = tempbuf; 874 rmsg.buf = tempbuf;
698 rmsg.size = 1024; 875 rmsg.size = sizeof(tempbuf);
699 876
700 if(!hwcrhk_context) 877 if(!hwcrhk_context)
701 { 878 {
702 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); 879 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
703 goto err; 880 goto err;
704 } 881 }
705 /* Prepare the params */ 882 /* Prepare the params */
@@ -723,11 +900,11 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
723 might be a good thing. */ 900 might be a good thing. */
724 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 901 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
725 { 902 {
726 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); 903 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FALLBACK);
727 } 904 }
728 else 905 else
729 { 906 {
730 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_REQUEST_FAILED); 907 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_REQUEST_FAILED);
731 } 908 }
732 ERR_add_error_data(1,rmsg.buf); 909 ERR_add_error_data(1,rmsg.buf);
733 goto err; 910 goto err;
@@ -737,38 +914,39 @@ static int hwcrhk_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
737err: 914err:
738 return to_return; 915 return to_return;
739 } 916 }
740 917
741static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa) 918#ifndef OPENSSL_NO_RSA
919static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa)
742 { 920 {
743 char tempbuf[1024]; 921 char tempbuf[1024];
744 HWCryptoHook_ErrMsgBuf rmsg; 922 HWCryptoHook_ErrMsgBuf rmsg;
745 HWCryptoHook_RSAKeyHandle *hptr; 923 HWCryptoHook_RSAKeyHandle *hptr;
746 int to_return = 0, ret; 924 int to_return = 0, ret;
747 925
926 rmsg.buf = tempbuf;
927 rmsg.size = sizeof(tempbuf);
928
748 if(!hwcrhk_context) 929 if(!hwcrhk_context)
749 { 930 {
750 ENGINEerr(ENGINE_F_HWCRHK_MOD_EXP,ENGINE_R_NOT_INITIALISED); 931 HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP,HWCRHK_R_NOT_INITIALISED);
751 goto err; 932 goto err;
752 } 933 }
753 934
754 /* This provides support for nForce keys. Since that's opaque data 935 /* This provides support for nForce keys. Since that's opaque data
755 all we do is provide a handle to the proper key and let HWCryptoHook 936 all we do is provide a handle to the proper key and let HWCryptoHook
756 take care of the rest. */ 937 take care of the rest. */
757 if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx)) 938 if ((hptr = (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa))
758 != NULL) 939 != NULL)
759 { 940 {
760 HWCryptoHook_MPI m_a, m_r; 941 HWCryptoHook_MPI m_a, m_r;
761 942
762 if(!rsa->n) 943 if(!rsa->n)
763 { 944 {
764 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, 945 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
765 ENGINE_R_MISSING_KEY_COMPONENTS); 946 HWCRHK_R_MISSING_KEY_COMPONENTS);
766 goto err; 947 goto err;
767 } 948 }
768 949
769 rmsg.buf = tempbuf;
770 rmsg.size = 1024;
771
772 /* Prepare the params */ 950 /* Prepare the params */
773 bn_expand2(r, rsa->n->top); /* Check for error !! */ 951 bn_expand2(r, rsa->n->top); /* Check for error !! */
774 BN2MPI(m_a, I); 952 BN2MPI(m_a, I);
@@ -788,11 +966,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
788 might be a good thing. */ 966 might be a good thing. */
789 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 967 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
790 { 968 {
791 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); 969 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
970 HWCRHK_R_REQUEST_FALLBACK);
792 } 971 }
793 else 972 else
794 { 973 {
795 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); 974 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
975 HWCRHK_R_REQUEST_FAILED);
796 } 976 }
797 ERR_add_error_data(1,rmsg.buf); 977 ERR_add_error_data(1,rmsg.buf);
798 goto err; 978 goto err;
@@ -804,14 +984,11 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
804 984
805 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) 985 if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp)
806 { 986 {
807 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP, 987 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
808 ENGINE_R_MISSING_KEY_COMPONENTS); 988 HWCRHK_R_MISSING_KEY_COMPONENTS);
809 goto err; 989 goto err;
810 } 990 }
811 991
812 rmsg.buf = tempbuf;
813 rmsg.size = 1024;
814
815 /* Prepare the params */ 992 /* Prepare the params */
816 bn_expand2(r, rsa->n->top); /* Check for error !! */ 993 bn_expand2(r, rsa->n->top); /* Check for error !! */
817 BN2MPI(m_a, I); 994 BN2MPI(m_a, I);
@@ -837,11 +1014,13 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
837 might be a good thing. */ 1014 might be a good thing. */
838 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 1015 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
839 { 1016 {
840 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FALLBACK); 1017 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1018 HWCRHK_R_REQUEST_FALLBACK);
841 } 1019 }
842 else 1020 else
843 { 1021 {
844 ENGINEerr(ENGINE_F_HWCRHK_RSA_MOD_EXP,ENGINE_R_REQUEST_FAILED); 1022 HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP,
1023 HWCRHK_R_REQUEST_FAILED);
845 } 1024 }
846 ERR_add_error_data(1,rmsg.buf); 1025 ERR_add_error_data(1,rmsg.buf);
847 goto err; 1026 goto err;
@@ -852,16 +1031,18 @@ static int hwcrhk_rsa_mod_exp(BIGNUM *r, BIGNUM *I, RSA *rsa)
852err: 1031err:
853 return to_return; 1032 return to_return;
854 } 1033 }
1034#endif
855 1035
856/* This function is aliased to mod_exp (with the mont stuff dropped). */ 1036/* This function is aliased to mod_exp (with the mont stuff dropped). */
857static int hwcrhk_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, 1037static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
858 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1038 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
859 { 1039 {
860 return hwcrhk_mod_exp(r, a, p, m, ctx); 1040 return hwcrhk_mod_exp(r, a, p, m, ctx);
861 } 1041 }
862 1042
863/* This function is aliased to mod_exp (with the dh and mont dropped). */ 1043/* This function is aliased to mod_exp (with the dh and mont dropped). */
864static int hwcrhk_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, 1044static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r,
1045 const BIGNUM *a, const BIGNUM *p,
865 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) 1046 const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
866 { 1047 {
867 return hwcrhk_mod_exp(r, a, p, m, ctx); 1048 return hwcrhk_mod_exp(r, a, p, m, ctx);
@@ -876,11 +1057,11 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num)
876 int ret; 1057 int ret;
877 1058
878 rmsg.buf = tempbuf; 1059 rmsg.buf = tempbuf;
879 rmsg.size = 1024; 1060 rmsg.size = sizeof(tempbuf);
880 1061
881 if(!hwcrhk_context) 1062 if(!hwcrhk_context)
882 { 1063 {
883 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_NOT_INITIALISED); 1064 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,HWCRHK_R_NOT_INITIALISED);
884 goto err; 1065 goto err;
885 } 1066 }
886 1067
@@ -892,11 +1073,13 @@ static int hwcrhk_rand_bytes(unsigned char *buf, int num)
892 might be a good thing. */ 1073 might be a good thing. */
893 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK) 1074 if(ret == HWCRYPTOHOOK_ERROR_FALLBACK)
894 { 1075 {
895 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FALLBACK); 1076 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
1077 HWCRHK_R_REQUEST_FALLBACK);
896 } 1078 }
897 else 1079 else
898 { 1080 {
899 ENGINEerr(ENGINE_F_HWCRHK_RAND_BYTES,ENGINE_R_REQUEST_FAILED); 1081 HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES,
1082 HWCRHK_R_REQUEST_FAILED);
900 } 1083 }
901 ERR_add_error_data(1,rmsg.buf); 1084 ERR_add_error_data(1,rmsg.buf);
902 goto err; 1085 goto err;
@@ -914,20 +1097,28 @@ static int hwcrhk_rand_status(void)
914/* This cleans up an RSA KM key, called when ex_data is freed */ 1097/* This cleans up an RSA KM key, called when ex_data is freed */
915 1098
916static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, 1099static void hwcrhk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad,
917 int index,long argl, void *argp) 1100 int ind,long argl, void *argp)
918{ 1101{
919 char tempbuf[1024]; 1102 char tempbuf[1024];
920 HWCryptoHook_ErrMsgBuf rmsg; 1103 HWCryptoHook_ErrMsgBuf rmsg;
1104#ifndef OPENSSL_NO_RSA
921 HWCryptoHook_RSAKeyHandle *hptr; 1105 HWCryptoHook_RSAKeyHandle *hptr;
1106#endif
1107#if !defined(OPENSSL_NO_RSA)
922 int ret; 1108 int ret;
1109#endif
923 1110
924 rmsg.buf = tempbuf; 1111 rmsg.buf = tempbuf;
925 rmsg.size = 1024; 1112 rmsg.size = sizeof(tempbuf);
926 1113
1114#ifndef OPENSSL_NO_RSA
927 hptr = (HWCryptoHook_RSAKeyHandle *) item; 1115 hptr = (HWCryptoHook_RSAKeyHandle *) item;
928 if(!hptr) return; 1116 if(hptr)
929 ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL); 1117 {
930 OPENSSL_free(hptr); 1118 ret = p_hwcrhk_RSAUnloadKey(*hptr, NULL);
1119 OPENSSL_free(hptr);
1120 }
1121#endif
931} 1122}
932 1123
933/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model 1124/* Mutex calls: since the HWCryptoHook model closely follows the POSIX model
@@ -939,17 +1130,17 @@ static int hwcrhk_mutex_init(HWCryptoHook_Mutex* mt,
939 { 1130 {
940 mt->lockid = CRYPTO_get_new_dynlockid(); 1131 mt->lockid = CRYPTO_get_new_dynlockid();
941 if (mt->lockid == 0) 1132 if (mt->lockid == 0)
942 return 0; 1133 return 1; /* failure */
943 return 1; 1134 return 0; /* success */
944 } 1135 }
945 1136
946static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt) 1137static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *mt)
947 { 1138 {
948 CRYPTO_w_lock(mt->lockid); 1139 CRYPTO_w_lock(mt->lockid);
949 return 1; 1140 return 0;
950 } 1141 }
951 1142
952void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) 1143static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt)
953 { 1144 {
954 CRYPTO_w_unlock(mt->lockid); 1145 CRYPTO_w_unlock(mt->lockid);
955 } 1146 }
@@ -964,50 +1155,146 @@ static int hwcrhk_get_pass(const char *prompt_info,
964 HWCryptoHook_PassphraseContext *ppctx, 1155 HWCryptoHook_PassphraseContext *ppctx,
965 HWCryptoHook_CallerContext *cactx) 1156 HWCryptoHook_CallerContext *cactx)
966 { 1157 {
967 int l = 0; 1158 pem_password_cb *callback = NULL;
968 char prompt[1024]; 1159 void *callback_data = NULL;
969 1160 UI_METHOD *ui_method = NULL;
970 if (password_callback == NULL) 1161
971 { 1162 if (cactx)
972 ENGINEerr(ENGINE_F_HWCRHK_GET_PASS,ENGINE_R_NO_CALLBACK); 1163 {
973 return -1; 1164 if (cactx->ui_method)
974 } 1165 ui_method = cactx->ui_method;
975 if (prompt_info) 1166 if (cactx->password_callback)
1167 callback = cactx->password_callback;
1168 if (cactx->callback_data)
1169 callback_data = cactx->callback_data;
1170 }
1171 if (ppctx)
976 { 1172 {
977 strncpy(prompt, "Card: \"", sizeof(prompt)); 1173 if (ppctx->ui_method)
978 l += 5; 1174 {
979 strncpy(prompt + l, prompt_info, sizeof(prompt) - l); 1175 ui_method = ppctx->ui_method;
980 l += strlen(prompt_info); 1176 callback = NULL;
981 if (l + 2 < sizeof(prompt)) 1177 }
982 { 1178 if (ppctx->callback_data)
983 strncpy(prompt + l, "\"\n", sizeof(prompt) - l); 1179 callback_data = ppctx->callback_data;
984 l += 2;
985 }
986 } 1180 }
987 if (l < sizeof(prompt) - 1) 1181 if (callback == NULL && ui_method == NULL)
988 { 1182 {
989 strncpy(prompt, "Enter Passphrase <enter to cancel>:", 1183 HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS,HWCRHK_R_NO_CALLBACK);
990 sizeof(prompt) - l); 1184 return -1;
991 l += 35;
992 } 1185 }
993 prompt[l] = '\0';
994 1186
995 /* I know, passing on the prompt instead of the user data *is* 1187 if (ui_method)
996 a bad thing. However, that's all we have right now. 1188 {
997 -- Richard Levitte */ 1189 UI *ui = UI_new_method(ui_method);
998 *len_io = password_callback(buf, *len_io, 0, prompt); 1190 if (ui)
1191 {
1192 int ok;
1193 char *prompt = UI_construct_prompt(ui,
1194 "pass phrase", prompt_info);
1195
1196 ok = UI_add_input_string(ui,prompt,
1197 UI_INPUT_FLAG_DEFAULT_PWD,
1198 buf,0,(*len_io) - 1);
1199 UI_add_user_data(ui, callback_data);
1200 UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
1201
1202 if (ok >= 0)
1203 do
1204 {
1205 ok=UI_process(ui);
1206 }
1207 while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
1208
1209 if (ok >= 0)
1210 *len_io = strlen(buf);
1211
1212 UI_free(ui);
1213 OPENSSL_free(prompt);
1214 }
1215 }
1216 else
1217 {
1218 *len_io = callback(buf, *len_io, 0, callback_data);
1219 }
999 if(!*len_io) 1220 if(!*len_io)
1000 return -1; 1221 return -1;
1001 return 0; 1222 return 0;
1002 } 1223 }
1003 1224
1004static void hwcrhk_log_message(void *logstream, const char *message) 1225static int hwcrhk_insert_card(const char *prompt_info,
1226 const char *wrong_info,
1227 HWCryptoHook_PassphraseContext *ppctx,
1228 HWCryptoHook_CallerContext *cactx)
1229 {
1230 int ok = -1;
1231 UI *ui;
1232 void *callback_data = NULL;
1233 UI_METHOD *ui_method = NULL;
1234
1235 if (cactx)
1236 {
1237 if (cactx->ui_method)
1238 ui_method = cactx->ui_method;
1239 if (cactx->callback_data)
1240 callback_data = cactx->callback_data;
1241 }
1242 if (ppctx)
1243 {
1244 if (ppctx->ui_method)
1245 ui_method = ppctx->ui_method;
1246 if (ppctx->callback_data)
1247 callback_data = ppctx->callback_data;
1248 }
1249 if (ui_method == NULL)
1250 {
1251 HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD,
1252 HWCRHK_R_NO_CALLBACK);
1253 return -1;
1254 }
1255
1256 ui = UI_new_method(ui_method);
1257
1258 if (ui)
1259 {
1260 char answer;
1261 char buf[BUFSIZ];
1262
1263 if (wrong_info)
1264 BIO_snprintf(buf, sizeof(buf)-1,
1265 "Current card: \"%s\"\n", wrong_info);
1266 ok = UI_dup_info_string(ui, buf);
1267 if (ok >= 0 && prompt_info)
1268 {
1269 BIO_snprintf(buf, sizeof(buf)-1,
1270 "Insert card \"%s\"", prompt_info);
1271 ok = UI_dup_input_boolean(ui, buf,
1272 "\n then hit <enter> or C<enter> to cancel\n",
1273 "\r\n", "Cc", UI_INPUT_FLAG_ECHO, &answer);
1274 }
1275 UI_add_user_data(ui, callback_data);
1276
1277 if (ok >= 0)
1278 ok = UI_process(ui);
1279 UI_free(ui);
1280
1281 if (ok == -2 || (ok >= 0 && answer == 'C'))
1282 ok = 1;
1283 else if (ok < 0)
1284 ok = -1;
1285 else
1286 ok = 0;
1287 }
1288 return ok;
1289 }
1290
1291static void hwcrhk_log_message(void *logstr, const char *message)
1005 { 1292 {
1006 BIO *lstream = NULL; 1293 BIO *lstream = NULL;
1007 1294
1008 CRYPTO_w_lock(CRYPTO_LOCK_BIO); 1295 CRYPTO_w_lock(CRYPTO_LOCK_BIO);
1009 if (logstream) 1296 if (logstr)
1010 lstream=*(BIO **)logstream; 1297 lstream=*(BIO **)logstr;
1011 if (lstream) 1298 if (lstream)
1012 { 1299 {
1013 BIO_write(lstream, message, strlen(message)); 1300 BIO_write(lstream, message, strlen(message));
@@ -1015,5 +1302,20 @@ static void hwcrhk_log_message(void *logstream, const char *message)
1015 CRYPTO_w_unlock(CRYPTO_LOCK_BIO); 1302 CRYPTO_w_unlock(CRYPTO_LOCK_BIO);
1016 } 1303 }
1017 1304
1018#endif /* !NO_HW_NCIPHER */ 1305/* This stuff is needed if this ENGINE is being compiled into a self-contained
1019#endif /* !NO_HW */ 1306 * shared-library. */
1307#ifdef ENGINE_DYNAMIC_SUPPORT
1308static int bind_fn(ENGINE *e, const char *id)
1309 {
1310 if(id && (strcmp(id, engine_hwcrhk_id) != 0))
1311 return 0;
1312 if(!bind_helper(e))
1313 return 0;
1314 return 1;
1315 }
1316IMPLEMENT_DYNAMIC_CHECK_FN()
1317IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
1318#endif /* ENGINE_DYNAMIC_SUPPORT */
1319
1320#endif /* !OPENSSL_NO_HW_NCIPHER */
1321#endif /* !OPENSSL_NO_HW */