summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine')
-rw-r--r--src/lib/libcrypto/engine/eng_all.c19
-rw-r--r--src/lib/libcrypto/engine/eng_cnf.c17
-rw-r--r--src/lib/libcrypto/engine/eng_ctrl.c8
-rw-r--r--src/lib/libcrypto/engine/eng_dyn.c14
-rw-r--r--src/lib/libcrypto/engine/eng_err.c6
-rw-r--r--src/lib/libcrypto/engine/eng_fat.c14
-rw-r--r--src/lib/libcrypto/engine/eng_int.h12
-rw-r--r--src/lib/libcrypto/engine/eng_lib.c3
-rw-r--r--src/lib/libcrypto/engine/eng_list.c2
-rw-r--r--src/lib/libcrypto/engine/eng_openssl.c2
-rw-r--r--src/lib/libcrypto/engine/eng_table.c72
-rw-r--r--src/lib/libcrypto/engine/engine.h55
-rw-r--r--src/lib/libcrypto/engine/tb_asnmth.c246
-rw-r--r--src/lib/libcrypto/engine/tb_pkmeth.c167
14 files changed, 580 insertions, 57 deletions
diff --git a/src/lib/libcrypto/engine/eng_all.c b/src/lib/libcrypto/engine/eng_all.c
index d29cd57dc2..22c120454f 100644
--- a/src/lib/libcrypto/engine/eng_all.c
+++ b/src/lib/libcrypto/engine/eng_all.c
@@ -61,15 +61,15 @@
61 61
62void ENGINE_load_builtin_engines(void) 62void ENGINE_load_builtin_engines(void)
63 { 63 {
64#if 0
64 /* There's no longer any need for an "openssl" ENGINE unless, one day, 65 /* There's no longer any need for an "openssl" ENGINE unless, one day,
65 * it is the *only* way for standard builtin implementations to be be 66 * it is the *only* way for standard builtin implementations to be be
66 * accessed (ie. it would be possible to statically link binaries with 67 * accessed (ie. it would be possible to statically link binaries with
67 * *no* builtin implementations). */ 68 * *no* builtin implementations). */
68#if 0
69 ENGINE_load_openssl(); 69 ENGINE_load_openssl();
70#endif 70#endif
71#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) 71#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
72 ENGINE_load_padlock(); 72 ENGINE_load_cryptodev();
73#endif 73#endif
74 ENGINE_load_dynamic(); 74 ENGINE_load_dynamic();
75#ifndef OPENSSL_NO_STATIC_ENGINE 75#ifndef OPENSSL_NO_STATIC_ENGINE
@@ -98,14 +98,15 @@ void ENGINE_load_builtin_engines(void)
98#ifndef OPENSSL_NO_HW_UBSEC 98#ifndef OPENSSL_NO_HW_UBSEC
99 ENGINE_load_ubsec(); 99 ENGINE_load_ubsec();
100#endif 100#endif
101#ifndef OPENSSL_NO_HW_PADLOCK
102 ENGINE_load_padlock();
101#endif 103#endif
102#if !defined(OPENSSL_NO_GMP) && !defined(OPENSSL_NO_HW_GMP)
103 ENGINE_load_gmp();
104#endif 104#endif
105#ifndef OPENSSL_NO_GOST
106 ENGINE_load_gost();
105#endif 107#endif
106#ifndef OPENSSL_NO_HW 108#ifndef OPENSSL_NO_GMP
107#if defined(__OpenBSD__) || defined(__FreeBSD__) 109 ENGINE_load_gmp();
108 ENGINE_load_cryptodev();
109#endif 110#endif
110#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 111#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
111 ENGINE_load_capi(); 112 ENGINE_load_capi();
@@ -113,7 +114,7 @@ void ENGINE_load_builtin_engines(void)
113#endif 114#endif
114 } 115 }
115 116
116#if defined(__OpenBSD__) || defined(__FreeBSD__) 117#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
117void ENGINE_setup_bsd_cryptodev(void) { 118void ENGINE_setup_bsd_cryptodev(void) {
118 static int bsd_cryptodev_default_loaded = 0; 119 static int bsd_cryptodev_default_loaded = 0;
119 if (!bsd_cryptodev_default_loaded) { 120 if (!bsd_cryptodev_default_loaded) {
diff --git a/src/lib/libcrypto/engine/eng_cnf.c b/src/lib/libcrypto/engine/eng_cnf.c
index 08066cea59..95c4070015 100644
--- a/src/lib/libcrypto/engine/eng_cnf.c
+++ b/src/lib/libcrypto/engine/eng_cnf.c
@@ -95,7 +95,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
95 int ret = 0; 95 int ret = 0;
96 long do_init = -1; 96 long do_init = -1;
97 STACK_OF(CONF_VALUE) *ecmds; 97 STACK_OF(CONF_VALUE) *ecmds;
98 CONF_VALUE *ecmd; 98 CONF_VALUE *ecmd = NULL;
99 char *ctrlname, *ctrlvalue; 99 char *ctrlname, *ctrlvalue;
100 ENGINE *e = NULL; 100 ENGINE *e = NULL;
101 int soft = 0; 101 int soft = 0;
@@ -157,7 +157,7 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
157 return 1; 157 return 1;
158 } 158 }
159 if (!e) 159 if (!e)
160 return 0; 160 goto err;
161 } 161 }
162 /* Allow "EMPTY" to mean no value: this allows a valid 162 /* Allow "EMPTY" to mean no value: this allows a valid
163 * "value" to be passed to ctrls of type NO_INPUT 163 * "value" to be passed to ctrls of type NO_INPUT
@@ -186,16 +186,27 @@ static int int_engine_configure(char *name, char *value, const CONF *cnf)
186 } 186 }
187 else if (!ENGINE_ctrl_cmd_string(e, 187 else if (!ENGINE_ctrl_cmd_string(e,
188 ctrlname, ctrlvalue, 0)) 188 ctrlname, ctrlvalue, 0))
189 return 0; 189 goto err;
190 } 190 }
191 191
192 192
193 193
194 } 194 }
195 if (e && (do_init == -1) && !int_engine_init(e)) 195 if (e && (do_init == -1) && !int_engine_init(e))
196 {
197 ecmd = NULL;
196 goto err; 198 goto err;
199 }
197 ret = 1; 200 ret = 1;
198 err: 201 err:
202 if (ret != 1)
203 {
204 ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_CONFIGURATION_ERROR);
205 if (ecmd)
206 ERR_add_error_data(6, "section=", ecmd->section,
207 ", name=", ecmd->name,
208 ", value=", ecmd->value);
209 }
199 if (e) 210 if (e)
200 ENGINE_free(e); 211 ENGINE_free(e);
201 return ret; 212 return ret;
diff --git a/src/lib/libcrypto/engine/eng_ctrl.c b/src/lib/libcrypto/engine/eng_ctrl.c
index 95b6b455aa..5ce25d92ec 100644
--- a/src/lib/libcrypto/engine/eng_ctrl.c
+++ b/src/lib/libcrypto/engine/eng_ctrl.c
@@ -280,7 +280,7 @@ int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
280 } 280 }
281 /* Force the result of the control command to 0 or 1, for the reasons 281 /* Force the result of the control command to 0 or 1, for the reasons
282 * mentioned before. */ 282 * mentioned before. */
283 if (ENGINE_ctrl(e, num, i, p, f)) 283 if (ENGINE_ctrl(e, num, i, p, f) > 0)
284 return 1; 284 return 1;
285 return 0; 285 return 0;
286 } 286 }
@@ -345,7 +345,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
345 * usage of these commands is consistent across applications and 345 * usage of these commands is consistent across applications and
346 * that certain applications don't understand it one way, and 346 * that certain applications don't understand it one way, and
347 * others another. */ 347 * others another. */
348 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) 348 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
349 return 1; 349 return 1;
350 return 0; 350 return 0;
351 } 351 }
@@ -360,7 +360,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
360 if(flags & ENGINE_CMD_FLAG_STRING) 360 if(flags & ENGINE_CMD_FLAG_STRING)
361 { 361 {
362 /* Same explanation as above */ 362 /* Same explanation as above */
363 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL)) 363 if(ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
364 return 1; 364 return 1;
365 return 0; 365 return 0;
366 } 366 }
@@ -383,7 +383,7 @@ int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
383 } 383 }
384 /* Force the result of the control command to 0 or 1, for the reasons 384 /* Force the result of the control command to 0 or 1, for the reasons
385 * mentioned before. */ 385 * mentioned before. */
386 if(ENGINE_ctrl(e, num, l, NULL, NULL)) 386 if(ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
387 return 1; 387 return 1;
388 return 0; 388 return 0;
389 } 389 }
diff --git a/src/lib/libcrypto/engine/eng_dyn.c b/src/lib/libcrypto/engine/eng_dyn.c
index acb30c34d8..807da7a5eb 100644
--- a/src/lib/libcrypto/engine/eng_dyn.c
+++ b/src/lib/libcrypto/engine/eng_dyn.c
@@ -146,14 +146,14 @@ struct st_dynamic_data_ctx
146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */ 146 * 'dirs' for loading. Default is to use 'dirs' as a fallback. */
147 int dir_load; 147 int dir_load;
148 /* A stack of directories from which ENGINEs could be loaded */ 148 /* A stack of directories from which ENGINEs could be loaded */
149 STACK *dirs; 149 STACK_OF(OPENSSL_STRING) *dirs;
150 }; 150 };
151 151
152/* This is the "ex_data" index we obtain and reserve for use with our context 152/* This is the "ex_data" index we obtain and reserve for use with our context
153 * structure. */ 153 * structure. */
154static int dynamic_ex_data_idx = -1; 154static int dynamic_ex_data_idx = -1;
155 155
156static void int_free_str(void *s) { OPENSSL_free(s); } 156static void int_free_str(char *s) { OPENSSL_free(s); }
157/* Because our ex_data element may or may not get allocated depending on whether 157/* 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 158 * 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 159 * problem to solve. We can't declare a "new" handler for the ex_data as we
@@ -174,7 +174,7 @@ static void dynamic_data_ctx_free_func(void *parent, void *ptr,
174 if(ctx->engine_id) 174 if(ctx->engine_id)
175 OPENSSL_free((void*)ctx->engine_id); 175 OPENSSL_free((void*)ctx->engine_id);
176 if(ctx->dirs) 176 if(ctx->dirs)
177 sk_pop_free(ctx->dirs, int_free_str); 177 sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
178 OPENSSL_free(ctx); 178 OPENSSL_free(ctx);
179 } 179 }
180 } 180 }
@@ -203,7 +203,7 @@ static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
203 c->DYNAMIC_F1 = "v_check"; 203 c->DYNAMIC_F1 = "v_check";
204 c->DYNAMIC_F2 = "bind_engine"; 204 c->DYNAMIC_F2 = "bind_engine";
205 c->dir_load = 1; 205 c->dir_load = 1;
206 c->dirs = sk_new_null(); 206 c->dirs = sk_OPENSSL_STRING_new_null();
207 if(!c->dirs) 207 if(!c->dirs)
208 { 208 {
209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE); 209 ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX,ERR_R_MALLOC_FAILURE);
@@ -393,7 +393,7 @@ static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
393 ERR_R_MALLOC_FAILURE); 393 ERR_R_MALLOC_FAILURE);
394 return 0; 394 return 0;
395 } 395 }
396 sk_insert(ctx->dirs, tmp_str, -1); 396 sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1);
397 } 397 }
398 return 1; 398 return 1;
399 default: 399 default:
@@ -411,11 +411,11 @@ static int int_load(dynamic_data_ctx *ctx)
411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL) 411 ctx->DYNAMIC_LIBNAME, NULL, 0)) != NULL)
412 return 1; 412 return 1;
413 /* If we're not allowed to use 'dirs' or we have none, fail */ 413 /* If we're not allowed to use 'dirs' or we have none, fail */
414 if(!ctx->dir_load || ((num = sk_num(ctx->dirs)) < 1)) 414 if(!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
415 return 0; 415 return 0;
416 for(loop = 0; loop < num; loop++) 416 for(loop = 0; loop < num; loop++)
417 { 417 {
418 const char *s = sk_value(ctx->dirs, loop); 418 const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); 419 char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
420 if(!merge) 420 if(!merge)
421 return 0; 421 return 0;
diff --git a/src/lib/libcrypto/engine/eng_err.c b/src/lib/libcrypto/engine/eng_err.c
index 574ffbb5c0..81c70acfa8 100644
--- a/src/lib/libcrypto/engine/eng_err.c
+++ b/src/lib/libcrypto/engine/eng_err.c
@@ -1,6 +1,6 @@
1/* crypto/engine/eng_err.c */ 1/* crypto/engine/eng_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -86,6 +86,8 @@ static ERR_STRING_DATA ENGINE_str_functs[]=
86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, 86{ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"},
87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, 87{ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
88{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"}, 88{ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
89{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), "ENGINE_get_pkey_asn1_meth"},
90{ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
89{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"}, 91{ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
90{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"}, 92{ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
91{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"}, 93{ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"},
@@ -124,6 +126,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
124{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"}, 126{ERR_REASON(ENGINE_R_DSO_FAILURE) ,"DSO failure"},
125{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"}, 127{ERR_REASON(ENGINE_R_DSO_NOT_FOUND) ,"dso not found"},
126{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"}, 128{ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR),"engines section error"},
129{ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),"engine configuration error"},
127{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"}, 130{ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST),"engine is not in the list"},
128{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"}, 131{ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR),"engine section error"},
129{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"}, 132{ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),"failed loading private key"},
@@ -150,6 +153,7 @@ static ERR_STRING_DATA ENGINE_str_reasons[]=
150{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"}, 153{ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED),"rsa not implemented"},
151{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"}, 154{ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER),"unimplemented cipher"},
152{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"}, 155{ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST),"unimplemented digest"},
156{ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),"unimplemented public key method"},
153{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"}, 157{ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY),"version incompatibility"},
154{0,NULL} 158{0,NULL}
155 }; 159 };
diff --git a/src/lib/libcrypto/engine/eng_fat.c b/src/lib/libcrypto/engine/eng_fat.c
index 27c1662f62..db66e62350 100644
--- a/src/lib/libcrypto/engine/eng_fat.c
+++ b/src/lib/libcrypto/engine/eng_fat.c
@@ -89,6 +89,12 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags)
89#endif 89#endif
90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) 90 if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
91 return 0; 91 return 0;
92 if((flags & ENGINE_METHOD_PKEY_METHS)
93 && !ENGINE_set_default_pkey_meths(e))
94 return 0;
95 if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
96 && !ENGINE_set_default_pkey_asn1_meths(e))
97 return 0;
92 return 1; 98 return 1;
93 } 99 }
94 100
@@ -115,6 +121,13 @@ static int int_def_cb(const char *alg, int len, void *arg)
115 *pflags |= ENGINE_METHOD_CIPHERS; 121 *pflags |= ENGINE_METHOD_CIPHERS;
116 else if (!strncmp(alg, "DIGESTS", len)) 122 else if (!strncmp(alg, "DIGESTS", len))
117 *pflags |= ENGINE_METHOD_DIGESTS; 123 *pflags |= ENGINE_METHOD_DIGESTS;
124 else if (!strncmp(alg, "PKEY", len))
125 *pflags |=
126 ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
127 else if (!strncmp(alg, "PKEY_CRYPTO", len))
128 *pflags |= ENGINE_METHOD_PKEY_METHS;
129 else if (!strncmp(alg, "PKEY_ASN1", len))
130 *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
118 else 131 else
119 return 0; 132 return 0;
120 return 1; 133 return 1;
@@ -154,6 +167,7 @@ int ENGINE_register_complete(ENGINE *e)
154 ENGINE_register_ECDSA(e); 167 ENGINE_register_ECDSA(e);
155#endif 168#endif
156 ENGINE_register_RAND(e); 169 ENGINE_register_RAND(e);
170 ENGINE_register_pkey_meths(e);
157 return 1; 171 return 1;
158 } 172 }
159 173
diff --git a/src/lib/libcrypto/engine/eng_int.h b/src/lib/libcrypto/engine/eng_int.h
index a66f107a44..451ef8feb8 100644
--- a/src/lib/libcrypto/engine/eng_int.h
+++ b/src/lib/libcrypto/engine/eng_int.h
@@ -127,6 +127,8 @@ ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
127ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l); 127ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l);
128#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) 128#define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__)
129#endif 129#endif
130typedef void (engine_table_doall_cb)(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg);
131void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, void *arg);
130 132
131/* Internal versions of API functions that have control over locking. These are 133/* Internal versions of API functions that have control over locking. These are
132 * used between C files when functionality needs to be shared but the caller may 134 * used between C files when functionality needs to be shared but the caller may
@@ -143,6 +145,11 @@ void engine_set_all_null(ENGINE *e);
143/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed 145/* NB: Bitwise OR-able values for the "flags" variable in ENGINE are now exposed
144 * in engine.h. */ 146 * in engine.h. */
145 147
148/* Free up dynamically allocated public key methods associated with ENGINE */
149
150void engine_pkey_meths_free(ENGINE *e);
151void engine_pkey_asn1_meths_free(ENGINE *e);
152
146/* This is a structure for storing implementations of various crypto 153/* This is a structure for storing implementations of various crypto
147 * algorithms and functions. */ 154 * algorithms and functions. */
148struct engine_st 155struct engine_st
@@ -160,7 +167,10 @@ struct engine_st
160 ENGINE_CIPHERS_PTR ciphers; 167 ENGINE_CIPHERS_PTR ciphers;
161 /* Digest handling is via this callback */ 168 /* Digest handling is via this callback */
162 ENGINE_DIGESTS_PTR digests; 169 ENGINE_DIGESTS_PTR digests;
163 170 /* Public key handling via this callback */
171 ENGINE_PKEY_METHS_PTR pkey_meths;
172 /* ASN1 public key handling via this callback */
173 ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
164 174
165 ENGINE_GEN_INT_FUNC_PTR destroy; 175 ENGINE_GEN_INT_FUNC_PTR destroy;
166 176
diff --git a/src/lib/libcrypto/engine/eng_lib.c b/src/lib/libcrypto/engine/eng_lib.c
index 5815b867f4..18a6664645 100644
--- a/src/lib/libcrypto/engine/eng_lib.c
+++ b/src/lib/libcrypto/engine/eng_lib.c
@@ -125,6 +125,9 @@ int engine_free_util(ENGINE *e, int locked)
125 abort(); 125 abort();
126 } 126 }
127#endif 127#endif
128 /* Free up any dynamically allocated public key methods */
129 engine_pkey_meths_free(e);
130 engine_pkey_asn1_meths_free(e);
128 /* Give the ENGINE a chance to do any structural cleanup corresponding 131 /* Give the ENGINE a chance to do any structural cleanup corresponding
129 * to allocation it did in its constructor (eg. unload error strings) */ 132 * to allocation it did in its constructor (eg. unload error strings) */
130 if(e->destroy) 133 if(e->destroy)
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
index bd511944ba..27846edb1e 100644
--- a/src/lib/libcrypto/engine/eng_list.c
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -336,6 +336,7 @@ static void engine_cpy(ENGINE *dest, const ENGINE *src)
336 dest->store_meth = src->store_meth; 336 dest->store_meth = src->store_meth;
337 dest->ciphers = src->ciphers; 337 dest->ciphers = src->ciphers;
338 dest->digests = src->digests; 338 dest->digests = src->digests;
339 dest->pkey_meths = src->pkey_meths;
339 dest->destroy = src->destroy; 340 dest->destroy = src->destroy;
340 dest->init = src->init; 341 dest->init = src->init;
341 dest->finish = src->finish; 342 dest->finish = src->finish;
@@ -412,6 +413,7 @@ ENGINE *ENGINE_by_id(const char *id)
412 return iterator; 413 return iterator;
413 } 414 }
414notfound: 415notfound:
416 ENGINE_free(iterator);
415 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE); 417 ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_ENGINE);
416 ERR_add_error_data(2, "id=", id); 418 ERR_add_error_data(2, "id=", id);
417 return NULL; 419 return NULL;
diff --git a/src/lib/libcrypto/engine/eng_openssl.c b/src/lib/libcrypto/engine/eng_openssl.c
index 7c139ae2ef..9abb95cc22 100644
--- a/src/lib/libcrypto/engine/eng_openssl.c
+++ b/src/lib/libcrypto/engine/eng_openssl.c
@@ -238,7 +238,7 @@ static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
238 return 1; 238 return 1;
239 } 239 }
240static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 240static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
241 const unsigned char *in, unsigned int inl) 241 const unsigned char *in, size_t inl)
242 { 242 {
243#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER 243#ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
244 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); 244 fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
diff --git a/src/lib/libcrypto/engine/eng_table.c b/src/lib/libcrypto/engine/eng_table.c
index 8879a267d1..4fde948185 100644
--- a/src/lib/libcrypto/engine/eng_table.c
+++ b/src/lib/libcrypto/engine/eng_table.c
@@ -70,12 +70,22 @@ typedef struct st_engine_pile
70 int uptodate; 70 int uptodate;
71 } ENGINE_PILE; 71 } ENGINE_PILE;
72 72
73DECLARE_LHASH_OF(ENGINE_PILE);
74
73/* The type exposed in eng_int.h */ 75/* The type exposed in eng_int.h */
74struct st_engine_table 76struct st_engine_table
75 { 77 {
76 LHASH piles; 78 LHASH_OF(ENGINE_PILE) piles;
77 }; /* ENGINE_TABLE */ 79 }; /* ENGINE_TABLE */
78 80
81
82typedef struct st_engine_pile_doall
83 {
84 engine_table_doall_cb *cb;
85 void *arg;
86 } ENGINE_PILE_DOALL;
87
88
79/* Global flags (ENGINE_TABLE_FLAG_***). */ 89/* Global flags (ENGINE_TABLE_FLAG_***). */
80static unsigned int table_flags = 0; 90static unsigned int table_flags = 0;
81 91
@@ -84,6 +94,7 @@ unsigned int ENGINE_get_table_flags(void)
84 { 94 {
85 return table_flags; 95 return table_flags;
86 } 96 }
97
87void ENGINE_set_table_flags(unsigned int flags) 98void ENGINE_set_table_flags(unsigned int flags)
88 { 99 {
89 table_flags = flags; 100 table_flags = flags;
@@ -94,19 +105,21 @@ static unsigned long engine_pile_hash(const ENGINE_PILE *c)
94 { 105 {
95 return c->nid; 106 return c->nid;
96 } 107 }
108
97static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) 109static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
98 { 110 {
99 return a->nid - b->nid; 111 return a->nid - b->nid;
100 } 112 }
101static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) 113static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE)
102static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) 114static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE)
115
103static int int_table_check(ENGINE_TABLE **t, int create) 116static int int_table_check(ENGINE_TABLE **t, int create)
104 { 117 {
105 LHASH *lh; 118 LHASH_OF(ENGINE_PILE) *lh;
119
106 if(*t) return 1; 120 if(*t) return 1;
107 if(!create) return 0; 121 if(!create) return 0;
108 if((lh = lh_new(LHASH_HASH_FN(engine_pile_hash), 122 if((lh = lh_ENGINE_PILE_new()) == NULL)
109 LHASH_COMP_FN(engine_pile_cmp))) == NULL)
110 return 0; 123 return 0;
111 *t = (ENGINE_TABLE *)lh; 124 *t = (ENGINE_TABLE *)lh;
112 return 1; 125 return 1;
@@ -130,7 +143,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
130 while(num_nids--) 143 while(num_nids--)
131 { 144 {
132 tmplate.nid = *nids; 145 tmplate.nid = *nids;
133 fnd = lh_retrieve(&(*table)->piles, &tmplate); 146 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
134 if(!fnd) 147 if(!fnd)
135 { 148 {
136 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); 149 fnd = OPENSSL_malloc(sizeof(ENGINE_PILE));
@@ -144,7 +157,7 @@ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
144 goto end; 157 goto end;
145 } 158 }
146 fnd->funct = NULL; 159 fnd->funct = NULL;
147 lh_insert(&(*table)->piles, fnd); 160 (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
148 } 161 }
149 /* A registration shouldn't add duplciate entries */ 162 /* A registration shouldn't add duplciate entries */
150 (void)sk_ENGINE_delete_ptr(fnd->sk, e); 163 (void)sk_ENGINE_delete_ptr(fnd->sk, e);
@@ -173,7 +186,7 @@ end:
173 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 186 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
174 return ret; 187 return ret;
175 } 188 }
176static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) 189static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e)
177 { 190 {
178 int n; 191 int n;
179 /* Iterate the 'c->sk' stack removing any occurance of 'e' */ 192 /* Iterate the 'c->sk' stack removing any occurance of 'e' */
@@ -188,31 +201,35 @@ static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
188 pile->funct = NULL; 201 pile->funct = NULL;
189 } 202 }
190 } 203 }
191static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) 204static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE)
205
192void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) 206void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
193 { 207 {
194 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 208 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
195 if(int_table_check(table, 0)) 209 if(int_table_check(table, 0))
196 lh_doall_arg(&(*table)->piles, 210 lh_ENGINE_PILE_doall_arg(&(*table)->piles,
197 LHASH_DOALL_ARG_FN(int_unregister_cb), e); 211 LHASH_DOALL_ARG_FN(int_unregister_cb),
212 ENGINE, e);
198 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 213 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
199 } 214 }
200 215
201static void int_cleanup_cb(ENGINE_PILE *p) 216static void int_cleanup_cb_doall(ENGINE_PILE *p)
202 { 217 {
203 sk_ENGINE_free(p->sk); 218 sk_ENGINE_free(p->sk);
204 if(p->funct) 219 if(p->funct)
205 engine_unlocked_finish(p->funct, 0); 220 engine_unlocked_finish(p->funct, 0);
206 OPENSSL_free(p); 221 OPENSSL_free(p);
207 } 222 }
208static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) 223static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE)
224
209void engine_table_cleanup(ENGINE_TABLE **table) 225void engine_table_cleanup(ENGINE_TABLE **table)
210 { 226 {
211 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 227 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
212 if(*table) 228 if(*table)
213 { 229 {
214 lh_doall(&(*table)->piles, LHASH_DOALL_FN(int_cleanup_cb)); 230 lh_ENGINE_PILE_doall(&(*table)->piles,
215 lh_free(&(*table)->piles); 231 LHASH_DOALL_FN(int_cleanup_cb));
232 lh_ENGINE_PILE_free(&(*table)->piles);
216 *table = NULL; 233 *table = NULL;
217 } 234 }
218 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 235 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
@@ -237,12 +254,13 @@ ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
237#endif 254#endif
238 return NULL; 255 return NULL;
239 } 256 }
257 ERR_set_mark();
240 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); 258 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
241 /* Check again inside the lock otherwise we could race against cleanup 259 /* Check again inside the lock otherwise we could race against cleanup
242 * operations. But don't worry about a fprintf(stderr). */ 260 * operations. But don't worry about a fprintf(stderr). */
243 if(!int_table_check(table, 0)) goto end; 261 if(!int_table_check(table, 0)) goto end;
244 tmplate.nid = nid; 262 tmplate.nid = nid;
245 fnd = lh_retrieve(&(*table)->piles, &tmplate); 263 fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
246 if(!fnd) goto end; 264 if(!fnd) goto end;
247 if(fnd->funct && engine_unlocked_init(fnd->funct)) 265 if(fnd->funct && engine_unlocked_init(fnd->funct))
248 { 266 {
@@ -310,6 +328,24 @@ end:
310 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); 328 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
311 /* Whatever happened, any failed init()s are not failures in this 329 /* Whatever happened, any failed init()s are not failures in this
312 * context, so clear our error state. */ 330 * context, so clear our error state. */
313 ERR_clear_error(); 331 ERR_pop_to_mark();
314 return ret; 332 return ret;
315 } 333 }
334
335/* Table enumeration */
336
337static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
338 {
339 dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
340 }
341static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL)
342
343void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
344 void *arg)
345 {
346 ENGINE_PILE_DOALL dall;
347 dall.cb = cb;
348 dall.arg = arg;
349 lh_ENGINE_PILE_doall_arg(&table->piles, LHASH_DOALL_ARG_FN(int_cb),
350 ENGINE_PILE_DOALL, &dall);
351 }
diff --git a/src/lib/libcrypto/engine/engine.h b/src/lib/libcrypto/engine/engine.h
index f503595ece..7fbd95f634 100644
--- a/src/lib/libcrypto/engine/engine.h
+++ b/src/lib/libcrypto/engine/engine.h
@@ -88,16 +88,15 @@
88#include <openssl/ecdsa.h> 88#include <openssl/ecdsa.h>
89#endif 89#endif
90#include <openssl/rand.h> 90#include <openssl/rand.h>
91#include <openssl/store.h>
92#include <openssl/ui.h> 91#include <openssl/ui.h>
93#include <openssl/err.h> 92#include <openssl/err.h>
94#endif 93#endif
95 94
96#include <openssl/x509.h>
97
98#include <openssl/ossl_typ.h> 95#include <openssl/ossl_typ.h>
99#include <openssl/symhacks.h> 96#include <openssl/symhacks.h>
100 97
98#include <openssl/x509.h>
99
101#ifdef __cplusplus 100#ifdef __cplusplus
102extern "C" { 101extern "C" {
103#endif 102#endif
@@ -113,6 +112,8 @@ extern "C" {
113#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 112#define ENGINE_METHOD_CIPHERS (unsigned int)0x0040
114#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 113#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
115#define ENGINE_METHOD_STORE (unsigned int)0x0100 114#define ENGINE_METHOD_STORE (unsigned int)0x0100
115#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
116#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
116/* Obvious all-or-nothing cases. */ 117/* Obvious all-or-nothing cases. */
117#define ENGINE_METHOD_ALL (unsigned int)0xFFFF 118#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
118#define ENGINE_METHOD_NONE (unsigned int)0x0000 119#define ENGINE_METHOD_NONE (unsigned int)0x0000
@@ -297,7 +298,8 @@ typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
297 * parameter is non-NULL it is set to the size of the returned array. */ 298 * parameter is non-NULL it is set to the size of the returned array. */
298typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int); 299typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
299typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int); 300typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
300 301typedef int (*ENGINE_PKEY_METHS_PTR)(ENGINE *, EVP_PKEY_METHOD **, const int **, int);
302typedef int (*ENGINE_PKEY_ASN1_METHS_PTR)(ENGINE *, EVP_PKEY_ASN1_METHOD **, const int **, int);
301/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE 303/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
302 * structures where the pointers have a "structural reference". This means that 304 * structures where the pointers have a "structural reference". This means that
303 * their reference is to allowed access to the structure but it does not imply 305 * their reference is to allowed access to the structure but it does not imply
@@ -329,19 +331,20 @@ void ENGINE_load_aep(void);
329void ENGINE_load_atalla(void); 331void ENGINE_load_atalla(void);
330void ENGINE_load_chil(void); 332void ENGINE_load_chil(void);
331void ENGINE_load_cswift(void); 333void ENGINE_load_cswift(void);
332#ifndef OPENSSL_NO_GMP
333void ENGINE_load_gmp(void);
334#endif
335void ENGINE_load_nuron(void); 334void ENGINE_load_nuron(void);
336void ENGINE_load_sureware(void); 335void ENGINE_load_sureware(void);
337void ENGINE_load_ubsec(void); 336void ENGINE_load_ubsec(void);
338#endif
339void ENGINE_load_cryptodev(void);
340void ENGINE_load_padlock(void); 337void ENGINE_load_padlock(void);
341void ENGINE_load_builtin_engines(void);
342#ifndef OPENSSL_NO_CAPIENG
343void ENGINE_load_capi(void); 338void ENGINE_load_capi(void);
339#ifndef OPENSSL_NO_GMP
340void ENGINE_load_gmp(void);
341#endif
342#ifndef OPENSSL_NO_GOST
343void ENGINE_load_gost(void);
344#endif
344#endif 345#endif
346void ENGINE_load_cryptodev(void);
347void ENGINE_load_builtin_engines(void);
345 348
346/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation 349/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
347 * "registry" handling. */ 350 * "registry" handling. */
@@ -392,6 +395,14 @@ int ENGINE_register_digests(ENGINE *e);
392void ENGINE_unregister_digests(ENGINE *e); 395void ENGINE_unregister_digests(ENGINE *e);
393void ENGINE_register_all_digests(void); 396void ENGINE_register_all_digests(void);
394 397
398int ENGINE_register_pkey_meths(ENGINE *e);
399void ENGINE_unregister_pkey_meths(ENGINE *e);
400void ENGINE_register_all_pkey_meths(void);
401
402int ENGINE_register_pkey_asn1_meths(ENGINE *e);
403void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
404void ENGINE_register_all_pkey_asn1_meths(void);
405
395/* These functions register all support from the above categories. Note, use of 406/* These functions register all support from the above categories. Note, use of
396 * these functions can result in static linkage of code your application may not 407 * these functions can result in static linkage of code your application may not
397 * need. If you only need a subset of functionality, consider using more 408 * need. If you only need a subset of functionality, consider using more
@@ -471,6 +482,8 @@ int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
471 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f); 482 ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
472int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); 483int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
473int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); 484int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
485int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
486int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
474int ENGINE_set_flags(ENGINE *e, int flags); 487int ENGINE_set_flags(ENGINE *e, int flags);
475int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); 488int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
476/* These functions allow control over any per-structure ENGINE data. */ 489/* These functions allow control over any per-structure ENGINE data. */
@@ -507,8 +520,16 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
507ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); 520ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
508ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); 521ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
509ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); 522ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
523ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
524ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
510const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); 525const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
511const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); 526const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
527const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
528const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
529const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
530 const char *str, int len);
531const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
532 const char *str, int len);
512const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); 533const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
513int ENGINE_get_flags(const ENGINE *e); 534int ENGINE_get_flags(const ENGINE *e);
514 535
@@ -560,6 +581,8 @@ ENGINE *ENGINE_get_default_RAND(void);
560 * ciphering or digesting corresponding to "nid". */ 581 * ciphering or digesting corresponding to "nid". */
561ENGINE *ENGINE_get_cipher_engine(int nid); 582ENGINE *ENGINE_get_cipher_engine(int nid);
562ENGINE *ENGINE_get_digest_engine(int nid); 583ENGINE *ENGINE_get_digest_engine(int nid);
584ENGINE *ENGINE_get_pkey_meth_engine(int nid);
585ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
563 586
564/* This sets a new default ENGINE structure for performing RSA 587/* This sets a new default ENGINE structure for performing RSA
565 * operations. If the result is non-zero (success) then the ENGINE 588 * operations. If the result is non-zero (success) then the ENGINE
@@ -575,6 +598,8 @@ int ENGINE_set_default_DH(ENGINE *e);
575int ENGINE_set_default_RAND(ENGINE *e); 598int ENGINE_set_default_RAND(ENGINE *e);
576int ENGINE_set_default_ciphers(ENGINE *e); 599int ENGINE_set_default_ciphers(ENGINE *e);
577int ENGINE_set_default_digests(ENGINE *e); 600int ENGINE_set_default_digests(ENGINE *e);
601int ENGINE_set_default_pkey_meths(ENGINE *e);
602int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
578 603
579/* The combination "set" - the flags are bitwise "OR"d from the 604/* The combination "set" - the flags are bitwise "OR"d from the
580 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" 605 * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
@@ -703,7 +728,7 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
703 * values. */ 728 * values. */
704void *ENGINE_get_static_state(void); 729void *ENGINE_get_static_state(void);
705 730
706#if defined(__OpenBSD__) || defined(__FreeBSD__) 731#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
707void ENGINE_setup_bsd_cryptodev(void); 732void ENGINE_setup_bsd_cryptodev(void);
708#endif 733#endif
709 734
@@ -732,13 +757,15 @@ void ERR_load_ENGINE_strings(void);
732#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 757#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177
733#define ENGINE_F_ENGINE_GET_DIGEST 186 758#define ENGINE_F_ENGINE_GET_DIGEST 186
734#define ENGINE_F_ENGINE_GET_NEXT 115 759#define ENGINE_F_ENGINE_GET_NEXT 115
760#define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193
761#define ENGINE_F_ENGINE_GET_PKEY_METH 192
735#define ENGINE_F_ENGINE_GET_PREV 116 762#define ENGINE_F_ENGINE_GET_PREV 116
736#define ENGINE_F_ENGINE_INIT 119 763#define ENGINE_F_ENGINE_INIT 119
737#define ENGINE_F_ENGINE_LIST_ADD 120 764#define ENGINE_F_ENGINE_LIST_ADD 120
738#define ENGINE_F_ENGINE_LIST_REMOVE 121 765#define ENGINE_F_ENGINE_LIST_REMOVE 121
739#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 766#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150
740#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 767#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151
741#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 192 768#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194
742#define ENGINE_F_ENGINE_NEW 122 769#define ENGINE_F_ENGINE_NEW 122
743#define ENGINE_F_ENGINE_REMOVE 123 770#define ENGINE_F_ENGINE_REMOVE 123
744#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 771#define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189
@@ -767,6 +794,7 @@ void ERR_load_ENGINE_strings(void);
767#define ENGINE_R_DSO_FAILURE 104 794#define ENGINE_R_DSO_FAILURE 104
768#define ENGINE_R_DSO_NOT_FOUND 132 795#define ENGINE_R_DSO_NOT_FOUND 132
769#define ENGINE_R_ENGINES_SECTION_ERROR 148 796#define ENGINE_R_ENGINES_SECTION_ERROR 148
797#define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102
770#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 798#define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105
771#define ENGINE_R_ENGINE_SECTION_ERROR 149 799#define ENGINE_R_ENGINE_SECTION_ERROR 149
772#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 800#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128
@@ -793,6 +821,7 @@ void ERR_load_ENGINE_strings(void);
793#define ENGINE_R_RSA_NOT_IMPLEMENTED 141 821#define ENGINE_R_RSA_NOT_IMPLEMENTED 141
794#define ENGINE_R_UNIMPLEMENTED_CIPHER 146 822#define ENGINE_R_UNIMPLEMENTED_CIPHER 146
795#define ENGINE_R_UNIMPLEMENTED_DIGEST 147 823#define ENGINE_R_UNIMPLEMENTED_DIGEST 147
824#define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101
796#define ENGINE_R_VERSION_INCOMPATIBILITY 145 825#define ENGINE_R_VERSION_INCOMPATIBILITY 145
797 826
798#ifdef __cplusplus 827#ifdef __cplusplus
diff --git a/src/lib/libcrypto/engine/tb_asnmth.c b/src/lib/libcrypto/engine/tb_asnmth.c
new file mode 100644
index 0000000000..75090339f7
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_asnmth.c
@@ -0,0 +1,246 @@
1/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56#include "asn1_locl.h"
57#include <openssl/evp.h>
58
59/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
60 * function that is used by EVP to hook in pkey_asn1_meth code and cache
61 * defaults (etc), will display brief debugging summaries to stderr with the
62 * 'nid'. */
63/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
64
65static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
66
67void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
68 {
69 engine_table_unregister(&pkey_asn1_meth_table, e);
70 }
71
72static void engine_unregister_all_pkey_asn1_meths(void)
73 {
74 engine_table_cleanup(&pkey_asn1_meth_table);
75 }
76
77int ENGINE_register_pkey_asn1_meths(ENGINE *e)
78 {
79 if(e->pkey_asn1_meths)
80 {
81 const int *nids;
82 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
83 if(num_nids > 0)
84 return engine_table_register(&pkey_asn1_meth_table,
85 engine_unregister_all_pkey_asn1_meths, e, nids,
86 num_nids, 0);
87 }
88 return 1;
89 }
90
91void ENGINE_register_all_pkey_asn1_meths(void)
92 {
93 ENGINE *e;
94
95 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
96 ENGINE_register_pkey_asn1_meths(e);
97 }
98
99int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
100 {
101 if(e->pkey_asn1_meths)
102 {
103 const int *nids;
104 int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
105 if(num_nids > 0)
106 return engine_table_register(&pkey_asn1_meth_table,
107 engine_unregister_all_pkey_asn1_meths, e, nids,
108 num_nids, 1);
109 }
110 return 1;
111 }
112
113/* Exposed API function to get a functional reference from the implementation
114 * table (ie. try to get a functional reference from the tabled structural
115 * references) for a given pkey_asn1_meth 'nid' */
116ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
117 {
118 return engine_table_select(&pkey_asn1_meth_table, nid);
119 }
120
121/* Obtains a pkey_asn1_meth implementation from an ENGINE functional reference */
122const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
123 {
124 EVP_PKEY_ASN1_METHOD *ret;
125 ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
126 if(!fn || !fn(e, &ret, NULL, nid))
127 {
128 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
129 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
130 return NULL;
131 }
132 return ret;
133 }
134
135/* Gets the pkey_asn1_meth callback from an ENGINE structure */
136ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
137 {
138 return e->pkey_asn1_meths;
139 }
140
141/* Sets the pkey_asn1_meth callback in an ENGINE structure */
142int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
143 {
144 e->pkey_asn1_meths = f;
145 return 1;
146 }
147
148/* Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
149 * ENGINE is destroyed
150 */
151
152void engine_pkey_asn1_meths_free(ENGINE *e)
153 {
154 int i;
155 EVP_PKEY_ASN1_METHOD *pkm;
156 if (e->pkey_asn1_meths)
157 {
158 const int *pknids;
159 int npknids;
160 npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
161 for (i = 0; i < npknids; i++)
162 {
163 if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i]))
164 {
165 EVP_PKEY_asn1_free(pkm);
166 }
167 }
168 }
169 }
170
171/* Find a method based on a string. This does a linear search through
172 * all implemented algorithms. This is OK in practice because only
173 * a small number of algorithms are likely to be implemented in an engine
174 * and it is not used for speed critical operations.
175 */
176
177const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
178 const char *str, int len)
179 {
180 int i, nidcount;
181 const int *nids;
182 EVP_PKEY_ASN1_METHOD *ameth;
183 if (!e->pkey_asn1_meths)
184 return NULL;
185 if (len == -1)
186 len = strlen(str);
187 nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
188 for (i = 0; i < nidcount; i++)
189 {
190 e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
191 if (((int)strlen(ameth->pem_str) == len) &&
192 !strncasecmp(ameth->pem_str, str, len))
193 return ameth;
194 }
195 return NULL;
196 }
197
198typedef struct
199 {
200 ENGINE *e;
201 const EVP_PKEY_ASN1_METHOD *ameth;
202 const char *str;
203 int len;
204 } ENGINE_FIND_STR;
205
206static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
207 {
208 ENGINE_FIND_STR *lk = arg;
209 int i;
210 if (lk->ameth)
211 return;
212 for (i = 0; i < sk_ENGINE_num(sk); i++)
213 {
214 ENGINE *e = sk_ENGINE_value(sk, i);
215 EVP_PKEY_ASN1_METHOD *ameth;
216 e->pkey_asn1_meths(e, &ameth, NULL, nid);
217 if (((int)strlen(ameth->pem_str) == lk->len) &&
218 !strncasecmp(ameth->pem_str, lk->str, lk->len))
219 {
220 lk->e = e;
221 lk->ameth = ameth;
222 return;
223 }
224 }
225 }
226
227const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
228 const char *str, int len)
229 {
230 ENGINE_FIND_STR fstr;
231 fstr.e = NULL;
232 fstr.ameth = NULL;
233 fstr.str = str;
234 fstr.len = len;
235 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
236 engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
237 /* If found obtain a structural reference to engine */
238 if (fstr.e)
239 {
240 fstr.e->struct_ref++;
241 engine_ref_debug(fstr.e, 0, 1)
242 }
243 *pe = fstr.e;
244 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
245 return fstr.ameth;
246 }
diff --git a/src/lib/libcrypto/engine/tb_pkmeth.c b/src/lib/libcrypto/engine/tb_pkmeth.c
new file mode 100644
index 0000000000..1cdb967f25
--- /dev/null
+++ b/src/lib/libcrypto/engine/tb_pkmeth.c
@@ -0,0 +1,167 @@
1/* ====================================================================
2 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * licensing@OpenSSL.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This product includes cryptographic software written by Eric Young
50 * (eay@cryptsoft.com). This product includes software written by Tim
51 * Hudson (tjh@cryptsoft.com).
52 *
53 */
54
55#include "eng_int.h"
56#include <openssl/evp.h>
57
58/* If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function
59 * that is used by EVP to hook in pkey_meth code and cache defaults (etc), will
60 * display brief debugging summaries to stderr with the 'nid'. */
61/* #define ENGINE_PKEY_METH_DEBUG */
62
63static ENGINE_TABLE *pkey_meth_table = NULL;
64
65void ENGINE_unregister_pkey_meths(ENGINE *e)
66 {
67 engine_table_unregister(&pkey_meth_table, e);
68 }
69
70static void engine_unregister_all_pkey_meths(void)
71 {
72 engine_table_cleanup(&pkey_meth_table);
73 }
74
75int ENGINE_register_pkey_meths(ENGINE *e)
76 {
77 if(e->pkey_meths)
78 {
79 const int *nids;
80 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
81 if(num_nids > 0)
82 return engine_table_register(&pkey_meth_table,
83 engine_unregister_all_pkey_meths, e, nids,
84 num_nids, 0);
85 }
86 return 1;
87 }
88
89void ENGINE_register_all_pkey_meths()
90 {
91 ENGINE *e;
92
93 for(e=ENGINE_get_first() ; e ; e=ENGINE_get_next(e))
94 ENGINE_register_pkey_meths(e);
95 }
96
97int ENGINE_set_default_pkey_meths(ENGINE *e)
98 {
99 if(e->pkey_meths)
100 {
101 const int *nids;
102 int num_nids = e->pkey_meths(e, NULL, &nids, 0);
103 if(num_nids > 0)
104 return engine_table_register(&pkey_meth_table,
105 engine_unregister_all_pkey_meths, e, nids,
106 num_nids, 1);
107 }
108 return 1;
109 }
110
111/* Exposed API function to get a functional reference from the implementation
112 * table (ie. try to get a functional reference from the tabled structural
113 * references) for a given pkey_meth 'nid' */
114ENGINE *ENGINE_get_pkey_meth_engine(int nid)
115 {
116 return engine_table_select(&pkey_meth_table, nid);
117 }
118
119/* Obtains a pkey_meth implementation from an ENGINE functional reference */
120const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
121 {
122 EVP_PKEY_METHOD *ret;
123 ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
124 if(!fn || !fn(e, &ret, NULL, nid))
125 {
126 ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
127 ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
128 return NULL;
129 }
130 return ret;
131 }
132
133/* Gets the pkey_meth callback from an ENGINE structure */
134ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
135 {
136 return e->pkey_meths;
137 }
138
139/* Sets the pkey_meth callback in an ENGINE structure */
140int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
141 {
142 e->pkey_meths = f;
143 return 1;
144 }
145
146/* Internal function to free up EVP_PKEY_METHOD structures before an
147 * ENGINE is destroyed
148 */
149
150void engine_pkey_meths_free(ENGINE *e)
151 {
152 int i;
153 EVP_PKEY_METHOD *pkm;
154 if (e->pkey_meths)
155 {
156 const int *pknids;
157 int npknids;
158 npknids = e->pkey_meths(e, NULL, &pknids, 0);
159 for (i = 0; i < npknids; i++)
160 {
161 if (e->pkey_meths(e, &pkm, NULL, pknids[i]))
162 {
163 EVP_PKEY_meth_free(pkm);
164 }
165 }
166 }
167 }