OLD | NEW |
1 /* ==================================================================== | 1 /* ==================================================================== |
2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. | 2 * Copyright (c) 2001 The OpenSSL Project. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * | 10 * |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 /* The 'nid' of this algorithm/mode */ | 63 /* The 'nid' of this algorithm/mode */ |
64 int nid; | 64 int nid; |
65 /* ENGINEs that implement this algorithm/mode. */ | 65 /* ENGINEs that implement this algorithm/mode. */ |
66 STACK_OF(ENGINE) *sk; | 66 STACK_OF(ENGINE) *sk; |
67 /* The default ENGINE to perform this algorithm/mode. */ | 67 /* The default ENGINE to perform this algorithm/mode. */ |
68 ENGINE *funct; | 68 ENGINE *funct; |
69 /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */ | 69 /* Zero if 'sk' is newer than the cached 'funct', non-zero otherwise */ |
70 int uptodate; | 70 int uptodate; |
71 } ENGINE_PILE; | 71 } ENGINE_PILE; |
72 | 72 |
| 73 DECLARE_LHASH_OF(ENGINE_PILE); |
| 74 |
73 /* The type exposed in eng_int.h */ | 75 /* The type exposed in eng_int.h */ |
74 struct st_engine_table | 76 struct st_engine_table |
75 { | 77 { |
76 » LHASH piles; | 78 » LHASH_OF(ENGINE_PILE) piles; |
77 }; /* ENGINE_TABLE */ | 79 }; /* ENGINE_TABLE */ |
78 | 80 |
| 81 |
| 82 typedef 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_***). */ |
80 static unsigned int table_flags = 0; | 90 static unsigned int table_flags = 0; |
81 | 91 |
82 /* API function manipulating 'table_flags' */ | 92 /* API function manipulating 'table_flags' */ |
83 unsigned int ENGINE_get_table_flags(void) | 93 unsigned int ENGINE_get_table_flags(void) |
84 { | 94 { |
85 return table_flags; | 95 return table_flags; |
86 } | 96 } |
| 97 |
87 void ENGINE_set_table_flags(unsigned int flags) | 98 void ENGINE_set_table_flags(unsigned int flags) |
88 { | 99 { |
89 table_flags = flags; | 100 table_flags = flags; |
90 } | 101 } |
91 | 102 |
92 /* Internal functions for the "piles" hash table */ | 103 /* Internal functions for the "piles" hash table */ |
93 static unsigned long engine_pile_hash(const ENGINE_PILE *c) | 104 static unsigned long engine_pile_hash(const ENGINE_PILE *c) |
94 { | 105 { |
95 return c->nid; | 106 return c->nid; |
96 } | 107 } |
| 108 |
97 static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) | 109 static 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 } |
101 static IMPLEMENT_LHASH_HASH_FN(engine_pile_hash, const ENGINE_PILE *) | 113 static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE) |
102 static IMPLEMENT_LHASH_COMP_FN(engine_pile_cmp, const ENGINE_PILE *) | 114 static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE) |
| 115 |
103 static int int_table_check(ENGINE_TABLE **t, int create) | 116 static 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; |
113 } | 126 } |
114 | 127 |
115 /* Privately exposed (via eng_int.h) functions for adding and/or removing | 128 /* Privately exposed (via eng_int.h) functions for adding and/or removing |
116 * ENGINEs from the implementation table */ | 129 * ENGINEs from the implementation table */ |
117 int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, | 130 int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, |
118 ENGINE *e, const int *nids, int num_nids, int setdefault) | 131 ENGINE *e, const int *nids, int num_nids, int setdefault) |
119 { | 132 { |
120 int ret = 0, added = 0; | 133 int ret = 0, added = 0; |
121 ENGINE_PILE tmplate, *fnd; | 134 ENGINE_PILE tmplate, *fnd; |
122 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | 135 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); |
123 if(!(*table)) | 136 if(!(*table)) |
124 added = 1; | 137 added = 1; |
125 if(!int_table_check(table, 1)) | 138 if(!int_table_check(table, 1)) |
126 goto end; | 139 goto end; |
127 if(added) | 140 if(added) |
128 /* The cleanup callback needs to be added */ | 141 /* The cleanup callback needs to be added */ |
129 engine_cleanup_add_first(cleanup); | 142 engine_cleanup_add_first(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)); |
137 if(!fnd) goto end; | 150 if(!fnd) goto end; |
138 fnd->uptodate = 1; | 151 fnd->uptodate = 1; |
139 fnd->nid = *nids; | 152 fnd->nid = *nids; |
140 fnd->sk = sk_ENGINE_new_null(); | 153 fnd->sk = sk_ENGINE_new_null(); |
141 if(!fnd->sk) | 154 if(!fnd->sk) |
142 { | 155 { |
143 OPENSSL_free(fnd); | 156 OPENSSL_free(fnd); |
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); |
151 /* if 'setdefault', this ENGINE goes to the head of the list */ | 164 /* if 'setdefault', this ENGINE goes to the head of the list */ |
152 if(!sk_ENGINE_push(fnd->sk, e)) | 165 if(!sk_ENGINE_push(fnd->sk, e)) |
153 goto end; | 166 goto end; |
154 /* "touch" this ENGINE_PILE */ | 167 /* "touch" this ENGINE_PILE */ |
155 fnd->uptodate = 0; | 168 fnd->uptodate = 0; |
156 if(setdefault) | 169 if(setdefault) |
157 { | 170 { |
158 if(!engine_unlocked_init(e)) | 171 if(!engine_unlocked_init(e)) |
159 { | 172 { |
160 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, | 173 ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, |
161 ENGINE_R_INIT_FAILED); | 174 ENGINE_R_INIT_FAILED); |
162 goto end; | 175 goto end; |
163 } | 176 } |
164 if(fnd->funct) | 177 if(fnd->funct) |
165 engine_unlocked_finish(fnd->funct, 0); | 178 engine_unlocked_finish(fnd->funct, 0); |
166 fnd->funct = e; | 179 fnd->funct = e; |
167 fnd->uptodate = 1; | 180 fnd->uptodate = 1; |
168 } | 181 } |
169 nids++; | 182 nids++; |
170 } | 183 } |
171 ret = 1; | 184 ret = 1; |
172 end: | 185 end: |
173 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | 186 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); |
174 return ret; | 187 return ret; |
175 } | 188 } |
176 static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e) | 189 static 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' */ |
180 while((n = sk_ENGINE_find(pile->sk, e)) >= 0) | 193 while((n = sk_ENGINE_find(pile->sk, e)) >= 0) |
181 { | 194 { |
182 (void)sk_ENGINE_delete(pile->sk, n); | 195 (void)sk_ENGINE_delete(pile->sk, n); |
183 pile->uptodate = 0; | 196 pile->uptodate = 0; |
184 } | 197 } |
185 if(pile->funct == e) | 198 if(pile->funct == e) |
186 { | 199 { |
187 engine_unlocked_finish(e, 0); | 200 engine_unlocked_finish(e, 0); |
188 pile->funct = NULL; | 201 pile->funct = NULL; |
189 } | 202 } |
190 } | 203 } |
191 static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb,ENGINE_PILE *,ENGINE *) | 204 static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE) |
| 205 |
192 void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) | 206 void 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 |
201 static void int_cleanup_cb(ENGINE_PILE *p) | 216 static 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 } |
208 static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb,ENGINE_PILE *) | 223 static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE) |
| 224 |
209 void engine_table_cleanup(ENGINE_TABLE **table) | 225 void 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); |
219 } | 236 } |
220 | 237 |
221 /* return a functional reference for a given 'nid' */ | 238 /* return a functional reference for a given 'nid' */ |
222 #ifndef ENGINE_TABLE_DEBUG | 239 #ifndef ENGINE_TABLE_DEBUG |
223 ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) | 240 ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) |
224 #else | 241 #else |
225 ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
t l) | 242 ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, in
t l) |
(...skipping 10 matching lines...) Expand all Loading... |
236 "registered!\n", f, l, nid); | 253 "registered!\n", f, l, nid); |
237 #endif | 254 #endif |
238 return NULL; | 255 return NULL; |
239 } | 256 } |
240 ERR_set_mark(); | 257 ERR_set_mark(); |
241 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); | 258 CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); |
242 /* Check again inside the lock otherwise we could race against cleanup | 259 /* Check again inside the lock otherwise we could race against cleanup |
243 * operations. But don't worry about a fprintf(stderr). */ | 260 * operations. But don't worry about a fprintf(stderr). */ |
244 if(!int_table_check(table, 0)) goto end; | 261 if(!int_table_check(table, 0)) goto end; |
245 tmplate.nid = nid; | 262 tmplate.nid = nid; |
246 » fnd = lh_retrieve(&(*table)->piles, &tmplate); | 263 » fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); |
247 if(!fnd) goto end; | 264 if(!fnd) goto end; |
248 if(fnd->funct && engine_unlocked_init(fnd->funct)) | 265 if(fnd->funct && engine_unlocked_init(fnd->funct)) |
249 { | 266 { |
250 #ifdef ENGINE_TABLE_DEBUG | 267 #ifdef ENGINE_TABLE_DEBUG |
251 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " | 268 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " |
252 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); | 269 "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); |
253 #endif | 270 #endif |
254 ret = fnd->funct; | 271 ret = fnd->funct; |
255 goto end; | 272 goto end; |
256 } | 273 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 else | 324 else |
308 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " | 325 fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " |
309 "'no matching ENGINE'\n", f, l, nid); | 326 "'no matching ENGINE'\n", f, l, nid); |
310 #endif | 327 #endif |
311 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); | 328 CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); |
312 /* Whatever happened, any failed init()s are not failures in this | 329 /* Whatever happened, any failed init()s are not failures in this |
313 * context, so clear our error state. */ | 330 * context, so clear our error state. */ |
314 ERR_pop_to_mark(); | 331 ERR_pop_to_mark(); |
315 return ret; | 332 return ret; |
316 } | 333 } |
| 334 |
| 335 /* Table enumeration */ |
| 336 |
| 337 static 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 } |
| 341 static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE,ENGINE_PILE_DOALL) |
| 342 |
| 343 void 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 } |
OLD | NEW |