summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_dyn.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/eng_dyn.c')
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c346
1 files changed, 175 insertions, 171 deletions
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
index e2de4603ee..0abb390b53 100644
--- a/src/lib/libcrypto/engine/eng_dyn.c
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -84,45 +84,52 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
84static const char *engine_dynamic_id = "dynamic"; 84static const char *engine_dynamic_id = "dynamic";
85static const char *engine_dynamic_name = "Dynamic engine loading support"; 85static const char *engine_dynamic_name = "Dynamic engine loading support";
86static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { 86static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
87 {DYNAMIC_CMD_SO_PATH, 87 {
88 DYNAMIC_CMD_SO_PATH,
88 "SO_PATH", 89 "SO_PATH",
89 "Specifies the path to the new ENGINE shared library", 90 "Specifies the path to the new ENGINE shared library",
90 ENGINE_CMD_FLAG_STRING}, 91 ENGINE_CMD_FLAG_STRING},
91 {DYNAMIC_CMD_NO_VCHECK, 92 {
93 DYNAMIC_CMD_NO_VCHECK,
92 "NO_VCHECK", 94 "NO_VCHECK",
93 "Specifies to continue even if version checking fails (boolean)", 95 "Specifies to continue even if version checking fails (boolean)",
94 ENGINE_CMD_FLAG_NUMERIC}, 96 ENGINE_CMD_FLAG_NUMERIC},
95 {DYNAMIC_CMD_ID, 97 {
98 DYNAMIC_CMD_ID,
96 "ID", 99 "ID",
97 "Specifies an ENGINE id name for loading", 100 "Specifies an ENGINE id name for loading",
98 ENGINE_CMD_FLAG_STRING}, 101 ENGINE_CMD_FLAG_STRING},
99 {DYNAMIC_CMD_LIST_ADD, 102 {
103 DYNAMIC_CMD_LIST_ADD,
100 "LIST_ADD", 104 "LIST_ADD",
101 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", 105 "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
102 ENGINE_CMD_FLAG_NUMERIC}, 106 ENGINE_CMD_FLAG_NUMERIC},
103 {DYNAMIC_CMD_DIR_LOAD, 107 {
108 DYNAMIC_CMD_DIR_LOAD,
104 "DIR_LOAD", 109 "DIR_LOAD",
105 "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)", 110 "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
106 ENGINE_CMD_FLAG_NUMERIC}, 111 ENGINE_CMD_FLAG_NUMERIC},
107 {DYNAMIC_CMD_DIR_ADD, 112 {
113 DYNAMIC_CMD_DIR_ADD,
108 "DIR_ADD", 114 "DIR_ADD",
109 "Adds a directory from which ENGINEs can be loaded", 115 "Adds a directory from which ENGINEs can be loaded",
110 ENGINE_CMD_FLAG_STRING}, 116 ENGINE_CMD_FLAG_STRING},
111 {DYNAMIC_CMD_LOAD, 117 {
118 DYNAMIC_CMD_LOAD,
112 "LOAD", 119 "LOAD",
113 "Load up the ENGINE specified by other settings", 120 "Load up the ENGINE specified by other settings",
114 ENGINE_CMD_FLAG_NO_INPUT}, 121 ENGINE_CMD_FLAG_NO_INPUT},
122
115 {0, NULL, NULL, 0} 123 {0, NULL, NULL, 0}
116 }; 124};
117static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = { 125static const ENGINE_CMD_DEFN dynamic_cmd_defns_empty[] = {
118 {0, NULL, NULL, 0} 126 {0, NULL, NULL, 0}
119 }; 127};
120 128
121/* Loading code stores state inside the ENGINE structure via the "ex_data" 129/* Loading code stores state inside the ENGINE structure via the "ex_data"
122 * element. We load all our state into a single structure and use that as a 130 * element. We load all our state into a single structure and use that as a
123 * single context in the "ex_data" stack. */ 131 * single context in the "ex_data" stack. */
124struct st_dynamic_data_ctx 132struct st_dynamic_data_ctx {
125 {
126 /* The DSO object we load that supplies the ENGINE code */ 133 /* The DSO object we load that supplies the ENGINE code */
127 DSO *dynamic_dso; 134 DSO *dynamic_dso;
128 /* The function pointer to the version checking shared library function */ 135 /* The function pointer to the version checking shared library function */
@@ -147,13 +154,18 @@ struct st_dynamic_data_ctx
147 int dir_load; 154 int dir_load;
148 /* A stack of directories from which ENGINEs could be loaded */ 155 /* A stack of directories from which ENGINEs could be loaded */
149 STACK_OF(OPENSSL_STRING) *dirs; 156 STACK_OF(OPENSSL_STRING) *dirs;
150 }; 157};
151 158
152/* This is the "ex_data" index we obtain and reserve for use with our context 159/* This is the "ex_data" index we obtain and reserve for use with our context
153 * structure. */ 160 * structure. */
154static int dynamic_ex_data_idx = -1; 161static int dynamic_ex_data_idx = -1;
155 162
156static void int_free_str(char *s) { free(s); } 163static void
164int_free_str(char *s)
165{
166 free(s);
167}
168
157/* Because our ex_data element may or may not get allocated depending on whether 169/* Because our ex_data element may or may not get allocated depending on whether
158 * a "first-use" occurs before the ENGINE is freed, we have a memory leak 170 * a "first-use" occurs before the ENGINE is freed, we have a memory leak
159 * problem to solve. We can't declare a "new" handler for the ex_data as we 171 * problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -161,35 +173,36 @@ static void int_free_str(char *s) { free(s); }
161 * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free" 173 * is a bug in the design of CRYPTO_EX_DATA). As such, we just declare a "free"
162 * handler and that will get called if an ENGINE is being destroyed and there 174 * handler and that will get called if an ENGINE is being destroyed and there
163 * was an ex_data element corresponding to our context type. */ 175 * was an ex_data element corresponding to our context type. */
164static void dynamic_data_ctx_free_func(void *parent, void *ptr, 176static void
165 CRYPTO_EX_DATA *ad, int idx, long argl, void *argp) 177dynamic_data_ctx_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
166 { 178 int idx, long argl, void *argp)
167 if(ptr) 179{
168 { 180 if (ptr) {
169 dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr; 181 dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
170 if(ctx->dynamic_dso) 182 if (ctx->dynamic_dso)
171 DSO_free(ctx->dynamic_dso); 183 DSO_free(ctx->dynamic_dso);
172 free((void *)ctx->DYNAMIC_LIBNAME); 184 free((void *)ctx->DYNAMIC_LIBNAME);
173 free((void *)ctx->engine_id); 185 free((void *)ctx->engine_id);
174 if(ctx->dirs) 186 if (ctx->dirs)
175 sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str); 187 sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
176 free(ctx); 188 free(ctx);
177 }
178 } 189 }
190}
179 191
180/* Construct the per-ENGINE context. We create it blindly and then use a lock to 192/* Construct the per-ENGINE context. We create it blindly and then use a lock to
181 * check for a race - if so, all but one of the threads "racing" will have 193 * check for a race - if so, all but one of the threads "racing" will have
182 * wasted their time. The alternative involves creating everything inside the 194 * wasted their time. The alternative involves creating everything inside the
183 * lock which is far worse. */ 195 * lock which is far worse. */
184static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) 196static int
185 { 197dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
198{
186 dynamic_data_ctx *c; 199 dynamic_data_ctx *c;
200
187 c = malloc(sizeof(dynamic_data_ctx)); 201 c = malloc(sizeof(dynamic_data_ctx));
188 if(!c) 202 if (!c) {
189 { 203 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE);
190 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
191 return 0; 204 return 0;
192 } 205 }
193 memset(c, 0, sizeof(dynamic_data_ctx)); 206 memset(c, 0, sizeof(dynamic_data_ctx));
194 c->dynamic_dso = NULL; 207 c->dynamic_dso = NULL;
195 c->v_check = NULL; 208 c->v_check = NULL;
@@ -202,89 +215,92 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
202 c->DYNAMIC_F2 = "bind_engine"; 215 c->DYNAMIC_F2 = "bind_engine";
203 c->dir_load = 1; 216 c->dir_load = 1;
204 c->dirs = sk_OPENSSL_STRING_new_null(); 217 c->dirs = sk_OPENSSL_STRING_new_null();
205 if(!c->dirs) 218 if (!c->dirs) {
206 { 219 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE);
207 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
208 free(c); 220 free(c);
209 return 0; 221 return 0;
210 } 222 }
211 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 223 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
212 if((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, 224 if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
213 dynamic_ex_data_idx)) == NULL) 225 dynamic_ex_data_idx)) == NULL) {
214 {
215 /* Good, we're the first */ 226 /* Good, we're the first */
216 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); 227 ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
217 *ctx = c; 228 *ctx = c;
218 c = NULL; 229 c = NULL;
219 } 230 }
220 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 231 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
221 /* If we lost the race to set the context, c is non-NULL and *ctx is the 232 /* If we lost the race to set the context, c is non-NULL and *ctx is the
222 * context of the thread that won. */ 233 * context of the thread that won. */
223 free(c); 234 free(c);
224 return 1; 235 return 1;
225 } 236}
226 237
227/* This function retrieves the context structure from an ENGINE's "ex_data", or 238/* This function retrieves the context structure from an ENGINE's "ex_data", or
228 * if it doesn't exist yet, sets it up. */ 239 * if it doesn't exist yet, sets it up. */
229static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) 240static dynamic_data_ctx *
230 { 241dynamic_get_data_ctx(ENGINE *e)
242{
231 dynamic_data_ctx *ctx; 243 dynamic_data_ctx *ctx;
232 if(dynamic_ex_data_idx < 0) 244 if (dynamic_ex_data_idx < 0) {
233 {
234 /* Create and register the ENGINE ex_data, and associate our 245 /* Create and register the ENGINE ex_data, and associate our
235 * "free" function with it to ensure any allocated contexts get 246 * "free" function with it to ensure any allocated contexts get
236 * freed when an ENGINE goes underground. */ 247 * freed when an ENGINE goes underground. */
237 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 248 int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
238 dynamic_data_ctx_free_func); 249 dynamic_data_ctx_free_func);
239 if(new_idx == -1) 250 if (new_idx == -1) {
240 { 251 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,
241 ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX,ENGINE_R_NO_INDEX); 252 ENGINE_R_NO_INDEX);
242 return NULL; 253 return NULL;
243 } 254 }
244 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 255 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
245 /* Avoid a race by checking again inside this lock */ 256 /* Avoid a race by checking again inside this lock */
246 if(dynamic_ex_data_idx < 0) 257 if (dynamic_ex_data_idx < 0) {
247 {
248 /* Good, someone didn't beat us to it */ 258 /* Good, someone didn't beat us to it */
249 dynamic_ex_data_idx = new_idx; 259 dynamic_ex_data_idx = new_idx;
250 new_idx = -1; 260 new_idx = -1;
251 } 261 }
252 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 262 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
253 /* In theory we could "give back" the index here if 263 /* In theory we could "give back" the index here if
254 * (new_idx>-1), but it's not possible and wouldn't gain us much 264 * (new_idx>-1), but it's not possible and wouldn't gain us much
255 * if it were. */ 265 * if it were. */
256 } 266 }
257 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); 267 ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
258 /* Check if the context needs to be created */ 268 /* Check if the context needs to be created */
259 if((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) 269 if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
260 /* "set_data" will set errors if necessary */ 270 /* "set_data" will set errors if necessary */
261 return NULL; 271 return NULL;
262 return ctx; 272 return ctx;
263 } 273}
264 274
265static ENGINE *engine_dynamic(void) 275static ENGINE *
266 { 276engine_dynamic(void)
277{
267 ENGINE *ret = ENGINE_new(); 278 ENGINE *ret = ENGINE_new();
268 if(!ret) 279
280 if (!ret)
269 return NULL; 281 return NULL;
270 if(!ENGINE_set_id(ret, engine_dynamic_id) || 282
271 !ENGINE_set_name(ret, engine_dynamic_name) || 283 if (!ENGINE_set_id(ret, engine_dynamic_id) ||
272 !ENGINE_set_init_function(ret, dynamic_init) || 284 !ENGINE_set_name(ret, engine_dynamic_name) ||
273 !ENGINE_set_finish_function(ret, dynamic_finish) || 285 !ENGINE_set_init_function(ret, dynamic_init) ||
274 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) || 286 !ENGINE_set_finish_function(ret, dynamic_finish) ||
275 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) || 287 !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
276 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) 288 !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
277 { 289 !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) {
278 ENGINE_free(ret); 290 ENGINE_free(ret);
279 return NULL; 291 return NULL;
280 }
281 return ret;
282 } 292 }
293 return ret;
294}
283 295
284void ENGINE_load_dynamic(void) 296void
285 { 297ENGINE_load_dynamic(void)
298{
286 ENGINE *toadd = engine_dynamic(); 299 ENGINE *toadd = engine_dynamic();
287 if(!toadd) return; 300
301 if (!toadd)
302 return;
303
288 ENGINE_add(toadd); 304 ENGINE_add(toadd);
289 /* If the "add" worked, it gets a structural reference. So either way, 305 /* If the "add" worked, it gets a structural reference. So either way,
290 * we release our just-created reference. */ 306 * we release our just-created reference. */
@@ -293,48 +309,47 @@ void ENGINE_load_dynamic(void)
293 * already added (eg. someone calling ENGINE_load_blah then calling 309 * already added (eg. someone calling ENGINE_load_blah then calling
294 * ENGINE_load_builtin_engines() perhaps). */ 310 * ENGINE_load_builtin_engines() perhaps). */
295 ERR_clear_error(); 311 ERR_clear_error();
296 } 312}
297 313
298static int dynamic_init(ENGINE *e) 314static int
299 { 315dynamic_init(ENGINE *e)
316{
300 /* We always return failure - the "dyanamic" engine itself can't be used 317 /* We always return failure - the "dyanamic" engine itself can't be used
301 * for anything. */ 318 * for anything. */
302 return 0; 319 return 0;
303 } 320}
304 321
305static int dynamic_finish(ENGINE *e) 322static int
306 { 323dynamic_finish(ENGINE *e)
324{
307 /* This should never be called on account of "dynamic_init" always 325 /* This should never be called on account of "dynamic_init" always
308 * failing. */ 326 * failing. */
309 return 0; 327 return 0;
310 } 328}
311 329
312static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) 330static int
313 { 331dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
332{
314 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); 333 dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
315 int initialised; 334 int initialised;
316 335
317 if(!ctx) 336 if (!ctx) {
318 { 337 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED);
319 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_NOT_LOADED);
320 return 0; 338 return 0;
321 } 339 }
322 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); 340 initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
323 /* All our control commands require the ENGINE to be uninitialised */ 341 /* All our control commands require the ENGINE to be uninitialised */
324 if(initialised) 342 if (initialised) {
325 { 343 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED);
326 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
327 ENGINE_R_ALREADY_LOADED);
328 return 0; 344 return 0;
329 } 345 }
330 switch(cmd) 346 switch (cmd) {
331 {
332 case DYNAMIC_CMD_SO_PATH: 347 case DYNAMIC_CMD_SO_PATH:
333 /* a NULL 'p' or a string of zero-length is the same thing */ 348 /* a NULL 'p' or a string of zero-length is the same thing */
334 if(p && (strlen((const char *)p) < 1)) 349 if (p && (strlen((const char *)p) < 1))
335 p = NULL; 350 p = NULL;
336 free((void *)ctx->DYNAMIC_LIBNAME); 351 free((void *)ctx->DYNAMIC_LIBNAME);
337 if(p) 352 if (p)
338 ctx->DYNAMIC_LIBNAME = BUF_strdup(p); 353 ctx->DYNAMIC_LIBNAME = BUF_strdup(p);
339 else 354 else
340 ctx->DYNAMIC_LIBNAME = NULL; 355 ctx->DYNAMIC_LIBNAME = NULL;
@@ -344,145 +359,138 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
344 return 1; 359 return 1;
345 case DYNAMIC_CMD_ID: 360 case DYNAMIC_CMD_ID:
346 /* a NULL 'p' or a string of zero-length is the same thing */ 361 /* a NULL 'p' or a string of zero-length is the same thing */
347 if(p && (strlen((const char *)p) < 1)) 362 if (p && (strlen((const char *)p) < 1))
348 p = NULL; 363 p = NULL;
349 free((void *)ctx->engine_id); 364 free((void *)ctx->engine_id);
350 if(p) 365 if (p)
351 ctx->engine_id = BUF_strdup(p); 366 ctx->engine_id = BUF_strdup(p);
352 else 367 else
353 ctx->engine_id = NULL; 368 ctx->engine_id = NULL;
354 return (ctx->engine_id ? 1 : 0); 369 return (ctx->engine_id ? 1 : 0);
355 case DYNAMIC_CMD_LIST_ADD: 370 case DYNAMIC_CMD_LIST_ADD:
356 if((i < 0) || (i > 2)) 371 if ((i < 0) || (i > 2)) {
357 {
358 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, 372 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
359 ENGINE_R_INVALID_ARGUMENT); 373 ENGINE_R_INVALID_ARGUMENT);
360 return 0; 374 return 0;
361 } 375 }
362 ctx->list_add_value = (int)i; 376 ctx->list_add_value = (int)i;
363 return 1; 377 return 1;
364 case DYNAMIC_CMD_LOAD: 378 case DYNAMIC_CMD_LOAD:
365 return dynamic_load(e, ctx); 379 return dynamic_load(e, ctx);
366 case DYNAMIC_CMD_DIR_LOAD: 380 case DYNAMIC_CMD_DIR_LOAD:
367 if((i < 0) || (i > 2)) 381 if ((i < 0) || (i > 2)) {
368 {
369 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, 382 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
370 ENGINE_R_INVALID_ARGUMENT); 383 ENGINE_R_INVALID_ARGUMENT);
371 return 0; 384 return 0;
372 } 385 }
373 ctx->dir_load = (int)i; 386 ctx->dir_load = (int)i;
374 return 1; 387 return 1;
375 case DYNAMIC_CMD_DIR_ADD: 388 case DYNAMIC_CMD_DIR_ADD:
376 /* a NULL 'p' or a string of zero-length is the same thing */ 389 /* a NULL 'p' or a string of zero-length is the same thing */
377 if(!p || (strlen((const char *)p) < 1)) 390 if (!p || (strlen((const char *)p) < 1)) {
378 {
379 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, 391 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
380 ENGINE_R_INVALID_ARGUMENT); 392 ENGINE_R_INVALID_ARGUMENT);
381 return 0; 393 return 0;
382 } 394 }
383 { 395 {
384 char *tmp_str = BUF_strdup(p); 396 char *tmp_str = BUF_strdup(p);
385 if(!tmp_str) 397 if (!tmp_str) {
386 { 398 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,
387 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, 399 ERR_R_MALLOC_FAILURE);
388 ERR_R_MALLOC_FAILURE); 400 return 0;
389 return 0;
390 } 401 }
391 sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1); 402 sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
392 } 403 }
393 return 1; 404 return 1;
394 default: 405 default:
395 break; 406 break;
396 }
397 ENGINEerr(ENGINE_F_DYNAMIC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
398 return 0;
399 } 407 }
408 ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
409 return 0;
410}
400 411
401static int int_load(dynamic_data_ctx *ctx) 412static int
402 { 413int_load(dynamic_data_ctx *ctx)
414{
403 int num, loop; 415 int num, loop;
416
404 /* Unless told not to, try a direct load */ 417 /* Unless told not to, try a direct load */
405 if((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso, 418 if ((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
406 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL) 419 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
407 return 1; 420 return 1;
408 /* If we're not allowed to use 'dirs' or we have none, fail */ 421 /* If we're not allowed to use 'dirs' or we have none, fail */
409 if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1) 422 if (!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
410 return 0; 423 return 0;
411 for(loop = 0; loop < num; loop++) 424 for (loop = 0; loop < num; loop++) {
412 {
413 const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop); 425 const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
414 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); 426 char *merge = DSO_merge(ctx->dynamic_dso,
415 if(!merge) 427 ctx->DYNAMIC_LIBNAME, s);
428 if (!merge)
416 return 0; 429 return 0;
417 if(DSO_load(ctx->dynamic_dso, merge, NULL, 0)) 430 if (DSO_load(ctx->dynamic_dso, merge, NULL, 0)) {
418 {
419 /* Found what we're looking for */ 431 /* Found what we're looking for */
420 free(merge); 432 free(merge);
421 return 1; 433 return 1;
422 }
423 free(merge);
424 } 434 }
425 return 0; 435 free(merge);
426 } 436 }
437 return 0;
438}
427 439
428static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) 440static int
429 { 441dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
442{
430 ENGINE cpy; 443 ENGINE cpy;
431 dynamic_fns fns; 444 dynamic_fns fns;
432 445
433 if(!ctx->dynamic_dso) 446 if (!ctx->dynamic_dso)
434 ctx->dynamic_dso = DSO_new(); 447 ctx->dynamic_dso = DSO_new();
435 if(!ctx->DYNAMIC_LIBNAME) 448 if (!ctx->DYNAMIC_LIBNAME) {
436 { 449 if (!ctx->engine_id)
437 if(!ctx->engine_id)
438 return 0; 450 return 0;
439 ctx->DYNAMIC_LIBNAME = 451 ctx->DYNAMIC_LIBNAME = DSO_convert_filename(ctx->dynamic_dso,
440 DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); 452 ctx->engine_id);
441 } 453 }
442 if(!int_load(ctx)) 454 if (!int_load(ctx)) {
443 {
444 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, 455 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
445 ENGINE_R_DSO_NOT_FOUND); 456 ENGINE_R_DSO_NOT_FOUND);
446 DSO_free(ctx->dynamic_dso); 457 DSO_free(ctx->dynamic_dso);
447 ctx->dynamic_dso = NULL; 458 ctx->dynamic_dso = NULL;
448 return 0; 459 return 0;
449 } 460 }
450 /* We have to find a bind function otherwise it'll always end badly */ 461 /* We have to find a bind function otherwise it'll always end badly */
451 if(!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func( 462 if (!(ctx->bind_engine = (dynamic_bind_engine)DSO_bind_func(
452 ctx->dynamic_dso, ctx->DYNAMIC_F2))) 463 ctx->dynamic_dso, ctx->DYNAMIC_F2))) {
453 {
454 ctx->bind_engine = NULL; 464 ctx->bind_engine = NULL;
455 DSO_free(ctx->dynamic_dso); 465 DSO_free(ctx->dynamic_dso);
456 ctx->dynamic_dso = NULL; 466 ctx->dynamic_dso = NULL;
457 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, 467 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
458 ENGINE_R_DSO_FAILURE); 468 ENGINE_R_DSO_FAILURE);
459 return 0; 469 return 0;
460 } 470 }
461 /* Do we perform version checking? */ 471 /* Do we perform version checking? */
462 if(!ctx->no_vcheck) 472 if (!ctx->no_vcheck) {
463 {
464 unsigned long vcheck_res = 0; 473 unsigned long vcheck_res = 0;
465 /* Now we try to find a version checking function and decide how 474 /* Now we try to find a version checking function and decide how
466 * to cope with failure if/when it fails. */ 475 * to cope with failure if/when it fails. */
467 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func( 476 ctx->v_check = (dynamic_v_check_fn)DSO_bind_func(
468 ctx->dynamic_dso, ctx->DYNAMIC_F1); 477 ctx->dynamic_dso, ctx->DYNAMIC_F1);
469 if(ctx->v_check) 478 if (ctx->v_check)
470 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); 479 vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
471 /* We fail if the version checker veto'd the load *or* if it is 480 /* We fail if the version checker veto'd the load *or* if it is
472 * deferring to us (by returning its version) and we think it is 481 * deferring to us (by returning its version) and we think it is
473 * too old. */ 482 * too old. */
474 if(vcheck_res < OSSL_DYNAMIC_OLDEST) 483 if (vcheck_res < OSSL_DYNAMIC_OLDEST) {
475 {
476 /* Fail */ 484 /* Fail */
477 ctx->bind_engine = NULL; 485 ctx->bind_engine = NULL;
478 ctx->v_check = NULL; 486 ctx->v_check = NULL;
479 DSO_free(ctx->dynamic_dso); 487 DSO_free(ctx->dynamic_dso);
480 ctx->dynamic_dso = NULL; 488 ctx->dynamic_dso = NULL;
481 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, 489 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
482 ENGINE_R_VERSION_INCOMPATIBILITY); 490 ENGINE_R_VERSION_INCOMPATIBILITY);
483 return 0; 491 return 0;
484 }
485 } 492 }
493 }
486 /* First binary copy the ENGINE structure so that we can roll back if 494 /* First binary copy the ENGINE structure so that we can roll back if
487 * the hand-over fails */ 495 * the hand-over fails */
488 memcpy(&cpy, e, sizeof(ENGINE)); 496 memcpy(&cpy, e, sizeof(ENGINE));
@@ -495,8 +503,8 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
495 fns.err_fns = ERR_get_implementation(); 503 fns.err_fns = ERR_get_implementation();
496 fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); 504 fns.ex_data_fns = CRYPTO_get_ex_data_implementation();
497 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, 505 CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb,
498 &fns.mem_fns.realloc_cb, 506 &fns.mem_fns.realloc_cb,
499 &fns.mem_fns.free_cb); 507 &fns.mem_fns.free_cb);
500 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); 508 fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback();
501 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); 509 fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback();
502 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); 510 fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback();
@@ -507,37 +515,33 @@ static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
507 engine_set_all_null(e); 515 engine_set_all_null(e);
508 516
509 /* Try to bind the ENGINE onto our own ENGINE structure */ 517 /* Try to bind the ENGINE onto our own ENGINE structure */
510 if(!ctx->bind_engine(e, ctx->engine_id, &fns)) 518 if (!ctx->bind_engine(e, ctx->engine_id, &fns)) {
511 {
512 ctx->bind_engine = NULL; 519 ctx->bind_engine = NULL;
513 ctx->v_check = NULL; 520 ctx->v_check = NULL;
514 DSO_free(ctx->dynamic_dso); 521 DSO_free(ctx->dynamic_dso);
515 ctx->dynamic_dso = NULL; 522 ctx->dynamic_dso = NULL;
516 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,ENGINE_R_INIT_FAILED); 523 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED);
517 /* Copy the original ENGINE structure back */ 524 /* Copy the original ENGINE structure back */
518 memcpy(e, &cpy, sizeof(ENGINE)); 525 memcpy(e, &cpy, sizeof(ENGINE));
519 return 0; 526 return 0;
520 } 527 }
521 /* Do we try to add this ENGINE to the internal list too? */ 528 /* Do we try to add this ENGINE to the internal list too? */
522 if(ctx->list_add_value > 0) 529 if (ctx->list_add_value > 0) {
523 { 530 if (!ENGINE_add(e)) {
524 if(!ENGINE_add(e))
525 {
526 /* Do we tolerate this or fail? */ 531 /* Do we tolerate this or fail? */
527 if(ctx->list_add_value > 1) 532 if (ctx->list_add_value > 1) {
528 {
529 /* Fail - NB: By this time, it's too late to 533 /* Fail - NB: By this time, it's too late to
530 * rollback, and trying to do so allows the 534 * rollback, and trying to do so allows the
531 * bind_engine() code to have created leaks. We 535 * bind_engine() code to have created leaks. We
532 * just have to fail where we are, after the 536 * just have to fail where we are, after the
533 * ENGINE has changed. */ 537 * ENGINE has changed. */
534 ENGINEerr(ENGINE_F_DYNAMIC_LOAD, 538 ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
535 ENGINE_R_CONFLICTING_ENGINE_ID); 539 ENGINE_R_CONFLICTING_ENGINE_ID);
536 return 0; 540 return 0;
537 } 541 }
538 /* Tolerate */ 542 /* Tolerate */
539 ERR_clear_error(); 543 ERR_clear_error();
540 }
541 } 544 }
542 return 1;
543 } 545 }
546 return 1;
547}