diff options
Diffstat (limited to 'src/lib/libcrypto/cryptlib.c')
-rw-r--r-- | src/lib/libcrypto/cryptlib.c | 303 |
1 files changed, 245 insertions, 58 deletions
diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c index 9a7e80b7f8..612b3b93b4 100644 --- a/src/lib/libcrypto/cryptlib.c +++ b/src/lib/libcrypto/cryptlib.c | |||
@@ -59,19 +59,22 @@ | |||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include <string.h> | 60 | #include <string.h> |
61 | #include "cryptlib.h" | 61 | #include "cryptlib.h" |
62 | #include "crypto.h" | 62 | #include <openssl/crypto.h> |
63 | #include "date.h" | 63 | #include <openssl/safestack.h> |
64 | 64 | ||
65 | #if defined(WIN32) || defined(WIN16) | 65 | #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) |
66 | static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ | 66 | static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | DECLARE_STACK_OF(CRYPTO_dynlock) | ||
70 | IMPLEMENT_STACK_OF(CRYPTO_dynlock) | ||
71 | |||
69 | /* real #defines in crypto.h, keep these upto date */ | 72 | /* real #defines in crypto.h, keep these upto date */ |
70 | static char* lock_names[CRYPTO_NUM_LOCKS] = | 73 | static const char* lock_names[CRYPTO_NUM_LOCKS] = |
71 | { | 74 | { |
72 | "<<ERROR>>", | 75 | "<<ERROR>>", |
73 | "err", | 76 | "err", |
74 | "err_hash", | 77 | "ex_data", |
75 | "x509", | 78 | "x509", |
76 | "x509_info", | 79 | "x509_info", |
77 | "x509_pkey", | 80 | "x509_pkey", |
@@ -84,100 +87,283 @@ static char* lock_names[CRYPTO_NUM_LOCKS] = | |||
84 | "ssl_ctx", | 87 | "ssl_ctx", |
85 | "ssl_cert", | 88 | "ssl_cert", |
86 | "ssl_session", | 89 | "ssl_session", |
90 | "ssl_sess_cert", | ||
87 | "ssl", | 91 | "ssl", |
88 | "rand", | 92 | "rand", |
93 | "rand2", | ||
89 | "debug_malloc", | 94 | "debug_malloc", |
90 | "BIO", | 95 | "BIO", |
91 | "bio_gethostbyname", | 96 | "gethostbyname", |
97 | "getservbyname", | ||
98 | "readdir", | ||
92 | "RSA_blinding", | 99 | "RSA_blinding", |
100 | "dh", | ||
101 | "debug_malloc2", | ||
102 | "dso", | ||
103 | "dynlock", | ||
104 | "engine", | ||
105 | "ui", | ||
106 | #if CRYPTO_NUM_LOCKS != 31 | ||
107 | # error "Inconsistency between crypto.h and cryptlib.c" | ||
108 | #endif | ||
93 | }; | 109 | }; |
94 | 110 | ||
111 | /* This is for applications to allocate new type names in the non-dynamic | ||
112 | array of lock names. These are numbered with positive numbers. */ | ||
95 | static STACK *app_locks=NULL; | 113 | static STACK *app_locks=NULL; |
96 | 114 | ||
97 | #ifndef NOPROTO | 115 | /* For applications that want a more dynamic way of handling threads, the |
116 | following stack is used. These are externally numbered with negative | ||
117 | numbers. */ | ||
118 | static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; | ||
119 | |||
120 | |||
98 | static void (MS_FAR *locking_callback)(int mode,int type, | 121 | static void (MS_FAR *locking_callback)(int mode,int type, |
99 | char *file,int line)=NULL; | 122 | const char *file,int line)=NULL; |
100 | static int (MS_FAR *add_lock_callback)(int *pointer,int amount, | 123 | static int (MS_FAR *add_lock_callback)(int *pointer,int amount, |
101 | int type,char *file,int line)=NULL; | 124 | int type,const char *file,int line)=NULL; |
102 | static unsigned long (MS_FAR *id_callback)(void)=NULL; | 125 | static unsigned long (MS_FAR *id_callback)(void)=NULL; |
103 | #else | 126 | static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) |
104 | static void (MS_FAR *locking_callback)()=NULL; | 127 | (const char *file,int line)=NULL; |
105 | static int (MS_FAR *add_lock_callback)()=NULL; | 128 | static void (MS_FAR *dynlock_lock_callback)(int mode, |
106 | static unsigned long (MS_FAR *id_callback)()=NULL; | 129 | struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL; |
107 | #endif | 130 | static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, |
131 | const char *file,int line)=NULL; | ||
108 | 132 | ||
109 | int CRYPTO_get_new_lockid(name) | 133 | int CRYPTO_get_new_lockid(char *name) |
110 | char *name; | ||
111 | { | 134 | { |
112 | char *str; | 135 | char *str; |
113 | int i; | 136 | int i; |
114 | 137 | ||
138 | #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) | ||
115 | /* A hack to make Visual C++ 5.0 work correctly when linking as | 139 | /* A hack to make Visual C++ 5.0 work correctly when linking as |
116 | * a DLL using /MT. Without this, the application cannot use | 140 | * a DLL using /MT. Without this, the application cannot use |
117 | * and floating point printf's. | 141 | * and floating point printf's. |
118 | * It also seems to be needed for Visual C 1.5 (win16) */ | 142 | * It also seems to be needed for Visual C 1.5 (win16) */ |
119 | #if defined(WIN32) || defined(WIN16) | ||
120 | SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; | 143 | SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; |
121 | #endif | 144 | #endif |
122 | 145 | ||
123 | if (app_locks == NULL) | 146 | if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) |
124 | if ((app_locks=sk_new_null()) == NULL) | 147 | { |
125 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); | 148 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); |
126 | return(0); | 149 | return(0); |
150 | } | ||
127 | if ((str=BUF_strdup(name)) == NULL) | 151 | if ((str=BUF_strdup(name)) == NULL) |
152 | { | ||
153 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); | ||
128 | return(0); | 154 | return(0); |
155 | } | ||
129 | i=sk_push(app_locks,str); | 156 | i=sk_push(app_locks,str); |
130 | if (!i) | 157 | if (!i) |
131 | Free(str); | 158 | OPENSSL_free(str); |
132 | else | 159 | else |
133 | i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ | 160 | i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ |
134 | return(i); | 161 | return(i); |
135 | } | 162 | } |
136 | 163 | ||
137 | void (*CRYPTO_get_locking_callback(P_V))(P_I_I_P_I) | 164 | int CRYPTO_num_locks(void) |
165 | { | ||
166 | return CRYPTO_NUM_LOCKS; | ||
167 | } | ||
168 | |||
169 | int CRYPTO_get_new_dynlockid(void) | ||
170 | { | ||
171 | int i = 0; | ||
172 | CRYPTO_dynlock *pointer = NULL; | ||
173 | |||
174 | if (dynlock_create_callback == NULL) | ||
175 | { | ||
176 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); | ||
177 | return(0); | ||
178 | } | ||
179 | CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); | ||
180 | if ((dyn_locks == NULL) | ||
181 | && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL)) | ||
182 | { | ||
183 | CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); | ||
184 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); | ||
185 | return(0); | ||
186 | } | ||
187 | CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); | ||
188 | |||
189 | pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock)); | ||
190 | if (pointer == NULL) | ||
191 | { | ||
192 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); | ||
193 | return(0); | ||
194 | } | ||
195 | pointer->references = 1; | ||
196 | pointer->data = dynlock_create_callback(__FILE__,__LINE__); | ||
197 | if (pointer->data == NULL) | ||
198 | { | ||
199 | OPENSSL_free(pointer); | ||
200 | CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); | ||
201 | return(0); | ||
202 | } | ||
203 | |||
204 | CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); | ||
205 | /* First, try to find an existing empty slot */ | ||
206 | i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); | ||
207 | /* If there was none, push, thereby creating a new one */ | ||
208 | if (i == -1) | ||
209 | i=sk_CRYPTO_dynlock_push(dyn_locks,pointer); | ||
210 | CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); | ||
211 | |||
212 | if (!i) | ||
213 | { | ||
214 | dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); | ||
215 | OPENSSL_free(pointer); | ||
216 | } | ||
217 | else | ||
218 | i += 1; /* to avoid 0 */ | ||
219 | return -i; | ||
220 | } | ||
221 | |||
222 | void CRYPTO_destroy_dynlockid(int i) | ||
223 | { | ||
224 | CRYPTO_dynlock *pointer = NULL; | ||
225 | if (i) | ||
226 | i = -i-1; | ||
227 | if (dynlock_destroy_callback == NULL) | ||
228 | return; | ||
229 | |||
230 | CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); | ||
231 | |||
232 | if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) | ||
233 | { | ||
234 | CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); | ||
235 | return; | ||
236 | } | ||
237 | pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); | ||
238 | if (pointer != NULL) | ||
239 | { | ||
240 | --pointer->references; | ||
241 | #ifdef REF_CHECK | ||
242 | if (pointer->references < 0) | ||
243 | { | ||
244 | fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n"); | ||
245 | abort(); | ||
246 | } | ||
247 | else | ||
248 | #endif | ||
249 | if (pointer->references <= 0) | ||
250 | { | ||
251 | sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); | ||
252 | } | ||
253 | else | ||
254 | pointer = NULL; | ||
255 | } | ||
256 | CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); | ||
257 | |||
258 | if (pointer) | ||
259 | { | ||
260 | dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); | ||
261 | OPENSSL_free(pointer); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) | ||
266 | { | ||
267 | CRYPTO_dynlock *pointer = NULL; | ||
268 | if (i) | ||
269 | i = -i-1; | ||
270 | |||
271 | CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); | ||
272 | |||
273 | if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) | ||
274 | pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); | ||
275 | if (pointer) | ||
276 | pointer->references++; | ||
277 | |||
278 | CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); | ||
279 | |||
280 | if (pointer) | ||
281 | return pointer->data; | ||
282 | return NULL; | ||
283 | } | ||
284 | |||
285 | struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) | ||
286 | (const char *file,int line) | ||
287 | { | ||
288 | return(dynlock_create_callback); | ||
289 | } | ||
290 | |||
291 | void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, | ||
292 | struct CRYPTO_dynlock_value *l, const char *file,int line) | ||
293 | { | ||
294 | return(dynlock_lock_callback); | ||
295 | } | ||
296 | |||
297 | void (*CRYPTO_get_dynlock_destroy_callback(void)) | ||
298 | (struct CRYPTO_dynlock_value *l, const char *file,int line) | ||
299 | { | ||
300 | return(dynlock_destroy_callback); | ||
301 | } | ||
302 | |||
303 | void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) | ||
304 | (const char *file, int line)) | ||
305 | { | ||
306 | dynlock_create_callback=func; | ||
307 | } | ||
308 | |||
309 | void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, | ||
310 | struct CRYPTO_dynlock_value *l, const char *file, int line)) | ||
311 | { | ||
312 | dynlock_lock_callback=func; | ||
313 | } | ||
314 | |||
315 | void CRYPTO_set_dynlock_destroy_callback(void (*func) | ||
316 | (struct CRYPTO_dynlock_value *l, const char *file, int line)) | ||
317 | { | ||
318 | dynlock_destroy_callback=func; | ||
319 | } | ||
320 | |||
321 | |||
322 | void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, | ||
323 | int line) | ||
138 | { | 324 | { |
139 | return(locking_callback); | 325 | return(locking_callback); |
140 | } | 326 | } |
141 | 327 | ||
142 | int (*CRYPTO_get_add_lock_callback(P_V))(P_IP_I_I_P_I) | 328 | int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, |
329 | const char *file,int line) | ||
143 | { | 330 | { |
144 | return(add_lock_callback); | 331 | return(add_lock_callback); |
145 | } | 332 | } |
146 | 333 | ||
147 | void CRYPTO_set_locking_callback(func) | 334 | void CRYPTO_set_locking_callback(void (*func)(int mode,int type, |
148 | void (*func)(P_I_I_P_I); | 335 | const char *file,int line)) |
149 | { | 336 | { |
150 | locking_callback=func; | 337 | locking_callback=func; |
151 | } | 338 | } |
152 | 339 | ||
153 | void CRYPTO_set_add_lock_callback(func) | 340 | void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, |
154 | int (*func)(P_IP_I_I_P_I); | 341 | const char *file,int line)) |
155 | { | 342 | { |
156 | add_lock_callback=func; | 343 | add_lock_callback=func; |
157 | } | 344 | } |
158 | 345 | ||
159 | unsigned long (*CRYPTO_get_id_callback(P_V))(P_V) | 346 | unsigned long (*CRYPTO_get_id_callback(void))(void) |
160 | { | 347 | { |
161 | return(id_callback); | 348 | return(id_callback); |
162 | } | 349 | } |
163 | 350 | ||
164 | void CRYPTO_set_id_callback(func) | 351 | void CRYPTO_set_id_callback(unsigned long (*func)(void)) |
165 | unsigned long (*func)(P_V); | ||
166 | { | 352 | { |
167 | id_callback=func; | 353 | id_callback=func; |
168 | } | 354 | } |
169 | 355 | ||
170 | unsigned long CRYPTO_thread_id() | 356 | unsigned long CRYPTO_thread_id(void) |
171 | { | 357 | { |
172 | unsigned long ret=0; | 358 | unsigned long ret=0; |
173 | 359 | ||
174 | if (id_callback == NULL) | 360 | if (id_callback == NULL) |
175 | { | 361 | { |
176 | #ifdef WIN16 | 362 | #ifdef OPENSSL_SYS_WIN16 |
177 | ret=(unsigned long)GetCurrentTask(); | 363 | ret=(unsigned long)GetCurrentTask(); |
178 | #elif defined(WIN32) | 364 | #elif defined(OPENSSL_SYS_WIN32) |
179 | ret=(unsigned long)GetCurrentThreadId(); | 365 | ret=(unsigned long)GetCurrentThreadId(); |
180 | #elif defined(MSDOS) | 366 | #elif defined(GETPID_IS_MEANINGLESS) |
181 | ret=1L; | 367 | ret=1L; |
182 | #else | 368 | #else |
183 | ret=(unsigned long)getpid(); | 369 | ret=(unsigned long)getpid(); |
@@ -188,11 +374,7 @@ unsigned long CRYPTO_thread_id() | |||
188 | return(ret); | 374 | return(ret); |
189 | } | 375 | } |
190 | 376 | ||
191 | void CRYPTO_lock(mode,type,file,line) | 377 | void CRYPTO_lock(int mode, int type, const char *file, int line) |
192 | int mode; | ||
193 | int type; | ||
194 | char *file; | ||
195 | int line; | ||
196 | { | 378 | { |
197 | #ifdef LOCK_DEBUG | 379 | #ifdef LOCK_DEBUG |
198 | { | 380 | { |
@@ -217,18 +399,27 @@ int line; | |||
217 | CRYPTO_get_lock_name(type), file, line); | 399 | CRYPTO_get_lock_name(type), file, line); |
218 | } | 400 | } |
219 | #endif | 401 | #endif |
220 | if (locking_callback != NULL) | 402 | if (type < 0) |
221 | locking_callback(mode,type,file,line); | 403 | { |
404 | struct CRYPTO_dynlock_value *pointer | ||
405 | = CRYPTO_get_dynlock_value(type); | ||
406 | |||
407 | if (pointer && dynlock_lock_callback) | ||
408 | { | ||
409 | dynlock_lock_callback(mode, pointer, file, line); | ||
410 | } | ||
411 | |||
412 | CRYPTO_destroy_dynlockid(type); | ||
413 | } | ||
414 | else | ||
415 | if (locking_callback != NULL) | ||
416 | locking_callback(mode,type,file,line); | ||
222 | } | 417 | } |
223 | 418 | ||
224 | int CRYPTO_add_lock(pointer,amount,type,file,line) | 419 | int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, |
225 | int *pointer; | 420 | int line) |
226 | int amount; | ||
227 | int type; | ||
228 | char *file; | ||
229 | int line; | ||
230 | { | 421 | { |
231 | int ret; | 422 | int ret = 0; |
232 | 423 | ||
233 | if (add_lock_callback != NULL) | 424 | if (add_lock_callback != NULL) |
234 | { | 425 | { |
@@ -244,7 +435,6 @@ int line; | |||
244 | CRYPTO_get_lock_name(type), | 435 | CRYPTO_get_lock_name(type), |
245 | file,line); | 436 | file,line); |
246 | #endif | 437 | #endif |
247 | *pointer=ret; | ||
248 | } | 438 | } |
249 | else | 439 | else |
250 | { | 440 | { |
@@ -264,11 +454,10 @@ int line; | |||
264 | return(ret); | 454 | return(ret); |
265 | } | 455 | } |
266 | 456 | ||
267 | char *CRYPTO_get_lock_name(type) | 457 | const char *CRYPTO_get_lock_name(int type) |
268 | int type; | ||
269 | { | 458 | { |
270 | if (type < 0) | 459 | if (type < 0) |
271 | return("ERROR"); | 460 | return("dynamic"); |
272 | else if (type < CRYPTO_NUM_LOCKS) | 461 | else if (type < CRYPTO_NUM_LOCKS) |
273 | return(lock_names[type]); | 462 | return(lock_names[type]); |
274 | else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks)) | 463 | else if (type-CRYPTO_NUM_LOCKS >= sk_num(app_locks)) |
@@ -278,15 +467,13 @@ int type; | |||
278 | } | 467 | } |
279 | 468 | ||
280 | #ifdef _DLL | 469 | #ifdef _DLL |
281 | #ifdef WIN32 | 470 | #ifdef OPENSSL_SYS_WIN32 |
282 | 471 | ||
283 | /* All we really need to do is remove the 'error' state when a thread | 472 | /* All we really need to do is remove the 'error' state when a thread |
284 | * detaches */ | 473 | * detaches */ |
285 | 474 | ||
286 | BOOL WINAPI DLLEntryPoint(hinstDLL,fdwReason,lpvReserved) | 475 | BOOL WINAPI DLLEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason, |
287 | HINSTANCE hinstDLL; | 476 | LPVOID lpvReserved) |
288 | DWORD fdwReason; | ||
289 | LPVOID lpvReserved; | ||
290 | { | 477 | { |
291 | switch(fdwReason) | 478 | switch(fdwReason) |
292 | { | 479 | { |