|
1 /* crypto/cryptlib.c */ |
|
2 /* ==================================================================== |
|
3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions |
|
7 * are met: |
|
8 * |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * |
|
12 * 2. Redistributions in binary form must reproduce the above copyright |
|
13 * notice, this list of conditions and the following disclaimer in |
|
14 * the documentation and/or other materials provided with the |
|
15 * distribution. |
|
16 * |
|
17 * 3. All advertising materials mentioning features or use of this |
|
18 * software must display the following acknowledgment: |
|
19 * "This product includes software developed by the OpenSSL Project |
|
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
|
21 * |
|
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
|
23 * endorse or promote products derived from this software without |
|
24 * prior written permission. For written permission, please contact |
|
25 * openssl-core@openssl.org. |
|
26 * |
|
27 * 5. Products derived from this software may not be called "OpenSSL" |
|
28 * nor may "OpenSSL" appear in their names without prior written |
|
29 * permission of the OpenSSL Project. |
|
30 * |
|
31 * 6. Redistributions of any form whatsoever must retain the following |
|
32 * acknowledgment: |
|
33 * "This product includes software developed by the OpenSSL Project |
|
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
|
35 * |
|
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
|
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
|
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|
47 * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
48 * ==================================================================== |
|
49 * |
|
50 * This product includes cryptographic software written by Eric Young |
|
51 * (eay@cryptsoft.com). This product includes software written by Tim |
|
52 * Hudson (tjh@cryptsoft.com). |
|
53 * |
|
54 */ |
|
55 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
|
56 * All rights reserved. |
|
57 * |
|
58 * This package is an SSL implementation written |
|
59 * by Eric Young (eay@cryptsoft.com). |
|
60 * The implementation was written so as to conform with Netscapes SSL. |
|
61 * |
|
62 * This library is free for commercial and non-commercial use as long as |
|
63 * the following conditions are aheared to. The following conditions |
|
64 * apply to all code found in this distribution, be it the RC4, RSA, |
|
65 * lhash, DES, etc., code; not just the SSL code. The SSL documentation |
|
66 * included with this distribution is covered by the same copyright terms |
|
67 * except that the holder is Tim Hudson (tjh@cryptsoft.com). |
|
68 * |
|
69 * Copyright remains Eric Young's, and as such any Copyright notices in |
|
70 * the code are not to be removed. |
|
71 * If this package is used in a product, Eric Young should be given attribution |
|
72 * as the author of the parts of the library used. |
|
73 * This can be in the form of a textual message at program startup or |
|
74 * in documentation (online or textual) provided with the package. |
|
75 * |
|
76 * Redistribution and use in source and binary forms, with or without |
|
77 * modification, are permitted provided that the following conditions |
|
78 * are met: |
|
79 * 1. Redistributions of source code must retain the copyright |
|
80 * notice, this list of conditions and the following disclaimer. |
|
81 * 2. Redistributions in binary form must reproduce the above copyright |
|
82 * notice, this list of conditions and the following disclaimer in the |
|
83 * documentation and/or other materials provided with the distribution. |
|
84 * 3. All advertising materials mentioning features or use of this software |
|
85 * must display the following acknowledgement: |
|
86 * "This product includes cryptographic software written by |
|
87 * Eric Young (eay@cryptsoft.com)" |
|
88 * The word 'cryptographic' can be left out if the rouines from the library |
|
89 * being used are not cryptographic related :-). |
|
90 * 4. If you include any Windows specific code (or a derivative thereof) from |
|
91 * the apps directory (application code) you must include an acknowledgement: |
|
92 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
|
93 * |
|
94 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
|
95 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
97 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
|
98 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
99 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
|
100 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
104 * SUCH DAMAGE. |
|
105 * |
|
106 * The licence and distribution terms for any publically available version or |
|
107 * derivative of this code cannot be changed. i.e. this code cannot simply be |
|
108 * copied and put under another distribution licence |
|
109 * [including the GNU Public Licence.] |
|
110 */ |
|
111 /* ==================================================================== |
|
112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. |
|
113 * ECDH support in OpenSSL originally developed by |
|
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. |
|
115 */ |
|
116 /* |
|
117 © Portions copyright (c) 2006 Nokia Corporation. All rights reserved. |
|
118 */ |
|
119 |
|
120 #include "cryptlib.h" |
|
121 #include <openssl/safestack.h> |
|
122 |
|
123 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) |
|
124 static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ |
|
125 #endif |
|
126 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__))) |
|
127 #include "libcrypto_wsd_macros.h" |
|
128 #include "libcrypto_wsd.h" |
|
129 #endif |
|
130 |
|
131 DECLARE_STACK_OF(CRYPTO_dynlock) |
|
132 IMPLEMENT_STACK_OF(CRYPTO_dynlock) |
|
133 |
|
134 /* real #defines in crypto.h, keep these upto date */ |
|
135 #ifndef EMULATOR |
|
136 static const char* lock_names[CRYPTO_NUM_LOCKS] = |
|
137 { |
|
138 "<<ERROR>>", |
|
139 "err", |
|
140 "ex_data", |
|
141 "x509", |
|
142 "x509_info", |
|
143 "x509_pkey", |
|
144 "x509_crl", |
|
145 "x509_req", |
|
146 "dsa", |
|
147 "rsa", |
|
148 "evp_pkey", |
|
149 "x509_store", |
|
150 "ssl_ctx", |
|
151 "ssl_cert", |
|
152 "ssl_session", |
|
153 "ssl_sess_cert", |
|
154 "ssl", |
|
155 "ssl_method", |
|
156 "rand", |
|
157 "rand2", |
|
158 "debug_malloc", |
|
159 "BIO", |
|
160 "gethostbyname", |
|
161 "getservbyname", |
|
162 "readdir", |
|
163 "RSA_blinding", |
|
164 "dh", |
|
165 "debug_malloc2", |
|
166 "dso", |
|
167 "dynlock", |
|
168 "engine", |
|
169 "ui", |
|
170 "ecdsa", |
|
171 "ec", |
|
172 "ecdh", |
|
173 "bn", |
|
174 "ec_pre_comp", |
|
175 "store", |
|
176 "comp", |
|
177 #if CRYPTO_NUM_LOCKS != 39 |
|
178 # error "Inconsistency between crypto.h and cryptlib.c" |
|
179 #endif |
|
180 }; |
|
181 #else |
|
182 |
|
183 static const char *const lock_names[CRYPTO_NUM_LOCKS] = |
|
184 { |
|
185 "<<ERROR>>", |
|
186 "err", |
|
187 "ex_data", |
|
188 "x509", |
|
189 "x509_info", |
|
190 "x509_pkey", |
|
191 "x509_crl", |
|
192 "x509_req", |
|
193 "dsa", |
|
194 "rsa", |
|
195 "evp_pkey", |
|
196 "x509_store", |
|
197 "ssl_ctx", |
|
198 "ssl_cert", |
|
199 "ssl_session", |
|
200 "ssl_sess_cert", |
|
201 "ssl", |
|
202 "ssl_method", |
|
203 "rand", |
|
204 "rand2", |
|
205 "debug_malloc", |
|
206 "BIO", |
|
207 "gethostbyname", |
|
208 "getservbyname", |
|
209 "readdir", |
|
210 "RSA_blinding", |
|
211 "dh", |
|
212 "debug_malloc2", |
|
213 "dso", |
|
214 "dynlock", |
|
215 "engine", |
|
216 "ui", |
|
217 "ecdsa", |
|
218 "ec", |
|
219 "ecdh", |
|
220 "bn", |
|
221 "ec_pre_comp", |
|
222 "store", |
|
223 "comp", |
|
224 #if CRYPTO_NUM_LOCKS != 39 |
|
225 # error "Inconsistency between crypto.h and cryptlib.c" |
|
226 #endif |
|
227 }; |
|
228 #endif //EMULATOR |
|
229 |
|
230 #ifndef EMULATOR |
|
231 /* This is for applications to allocate new type names in the non-dynamic |
|
232 array of lock names. These are numbered with positive numbers. */ |
|
233 static STACK *app_locks=NULL; |
|
234 /* For applications that want a more dynamic way of handling threads, the |
|
235 following stack is used. These are externally numbered with negative |
|
236 numbers. */ |
|
237 static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; |
|
238 |
|
239 #else |
|
240 GET_STATIC_VAR_FROM_TLS(app_locks,cryptlib,STACK *) |
|
241 #define app_locks (*GET_WSD_VAR_NAME(app_locks,cryptlib,s)()) |
|
242 GET_STATIC_VAR_FROM_TLS(dyn_locks,cryptlib,STACK_OF(CRYPTO_dynlock)*) |
|
243 #define dyn_locks (*GET_WSD_VAR_NAME(dyn_locks,cryptlib,s)()) |
|
244 #endif |
|
245 |
|
246 #ifndef EMULATOR |
|
247 static void (MS_FAR *locking_callback)(int mode,int type, |
|
248 const char *file,int line)=NULL; |
|
249 static int (MS_FAR *add_lock_callback)(int *pointer,int amount, |
|
250 int type,const char *file,int line)=NULL; |
|
251 static unsigned long (MS_FAR *id_callback)(void)=NULL; |
|
252 static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) |
|
253 (const char *file,int line)=NULL; |
|
254 static void (MS_FAR *dynlock_lock_callback)(int mode, |
|
255 struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL; |
|
256 static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, |
|
257 const char *file,int line)=NULL; |
|
258 #else |
|
259 #define locking_callback libcrypto_ImpurePtr()->locking_callback |
|
260 #define add_lock_callback libcrypto_ImpurePtr()->add_lock_callback |
|
261 #define id_callback libcrypto_ImpurePtr()->id_callback |
|
262 #define dynlock_create_callback libcrypto_ImpurePtr()->dynlock_create_callback |
|
263 #define dynlock_lock_callback libcrypto_ImpurePtr()->dynlock_lock_callback |
|
264 #define dynlock_destroy_callback libcrypto_ImpurePtr()->dynlock_destroy_callback |
|
265 #endif |
|
266 |
|
267 EXPORT_C int CRYPTO_get_new_lockid(char *name) |
|
268 { |
|
269 char *str; |
|
270 int i; |
|
271 |
|
272 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) |
|
273 /* A hack to make Visual C++ 5.0 work correctly when linking as |
|
274 * a DLL using /MT. Without this, the application cannot use |
|
275 * and floating point printf's. |
|
276 * It also seems to be needed for Visual C 1.5 (win16) */ |
|
277 SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; |
|
278 #endif |
|
279 |
|
280 if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL)) |
|
281 { |
|
282 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); |
|
283 return(0); |
|
284 } |
|
285 if ((str=BUF_strdup(name)) == NULL) |
|
286 { |
|
287 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); |
|
288 return(0); |
|
289 } |
|
290 i=sk_push(app_locks,str); |
|
291 if (!i) |
|
292 OPENSSL_free(str); |
|
293 else |
|
294 i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ |
|
295 return(i); |
|
296 } |
|
297 |
|
298 EXPORT_C int CRYPTO_num_locks(void) |
|
299 { |
|
300 return CRYPTO_NUM_LOCKS; |
|
301 } |
|
302 |
|
303 EXPORT_C int CRYPTO_get_new_dynlockid(void) |
|
304 { |
|
305 int i = 0; |
|
306 CRYPTO_dynlock *pointer = NULL; |
|
307 |
|
308 if (dynlock_create_callback == NULL) |
|
309 { |
|
310 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); |
|
311 return(0); |
|
312 } |
|
313 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
|
314 if ((dyn_locks == NULL)&&((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL)) |
|
315 { |
|
316 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
|
317 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); |
|
318 return(0); |
|
319 } |
|
320 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
|
321 |
|
322 pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock)); |
|
323 if (pointer == NULL) |
|
324 { |
|
325 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); |
|
326 return(0); |
|
327 } |
|
328 pointer->references = 1; |
|
329 pointer->data = dynlock_create_callback(__FILE__,__LINE__); |
|
330 if (pointer->data == NULL) |
|
331 { |
|
332 OPENSSL_free(pointer); |
|
333 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE); |
|
334 return(0); |
|
335 } |
|
336 |
|
337 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
|
338 /* First, try to find an existing empty slot */ |
|
339 i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); |
|
340 /* If there was none, push, thereby creating a new one */ |
|
341 if (i == -1) |
|
342 /* Since sk_push() returns the number of items on the |
|
343 stack, not the location of the pushed item, we need |
|
344 to transform the returned number into a position, |
|
345 by decreasing it. */ |
|
346 i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1; |
|
347 else |
|
348 /* If we found a place with a NULL pointer, put our pointer |
|
349 in it. */ |
|
350 (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); |
|
351 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
|
352 |
|
353 if (i == -1) |
|
354 { |
|
355 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); |
|
356 OPENSSL_free(pointer); |
|
357 } |
|
358 else |
|
359 i += 1; /* to avoid 0 */ |
|
360 return -i; |
|
361 } |
|
362 |
|
363 EXPORT_C void CRYPTO_destroy_dynlockid(int i) |
|
364 { |
|
365 CRYPTO_dynlock *pointer = NULL; |
|
366 if (i) |
|
367 i = -i-1; |
|
368 if (dynlock_destroy_callback == NULL) |
|
369 return; |
|
370 |
|
371 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
|
372 |
|
373 if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) |
|
374 { |
|
375 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
|
376 return; |
|
377 } |
|
378 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); |
|
379 if (pointer != NULL) |
|
380 { |
|
381 --pointer->references; |
|
382 #ifdef REF_CHECK |
|
383 if (pointer->references < 0) |
|
384 { |
|
385 fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n"); |
|
386 abort(); |
|
387 } |
|
388 else |
|
389 #endif |
|
390 if (pointer->references <= 0) |
|
391 { |
|
392 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); |
|
393 } |
|
394 else |
|
395 pointer = NULL; |
|
396 } |
|
397 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
|
398 |
|
399 if (pointer) |
|
400 { |
|
401 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); |
|
402 OPENSSL_free(pointer); |
|
403 } |
|
404 } |
|
405 |
|
406 EXPORT_C struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) |
|
407 { |
|
408 CRYPTO_dynlock *pointer = NULL; |
|
409 if (i) |
|
410 i = -i-1; |
|
411 |
|
412 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
|
413 |
|
414 if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) |
|
415 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); |
|
416 if (pointer) |
|
417 pointer->references++; |
|
418 |
|
419 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
|
420 |
|
421 if (pointer) |
|
422 return pointer->data; |
|
423 return NULL; |
|
424 } |
|
425 |
|
426 EXPORT_C struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) |
|
427 (const char *file,int line) |
|
428 { |
|
429 return(dynlock_create_callback); |
|
430 } |
|
431 |
|
432 EXPORT_C void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, |
|
433 struct CRYPTO_dynlock_value *l, const char *file,int line) |
|
434 { |
|
435 return(dynlock_lock_callback); |
|
436 } |
|
437 |
|
438 EXPORT_C void (*CRYPTO_get_dynlock_destroy_callback(void)) |
|
439 (struct CRYPTO_dynlock_value *l, const char *file,int line) |
|
440 { |
|
441 return(dynlock_destroy_callback); |
|
442 } |
|
443 |
|
444 EXPORT_C void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) |
|
445 (const char *file, int line)) |
|
446 { |
|
447 dynlock_create_callback=func; |
|
448 } |
|
449 |
|
450 EXPORT_C void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, |
|
451 struct CRYPTO_dynlock_value *l, const char *file, int line)) |
|
452 { |
|
453 dynlock_lock_callback=func; |
|
454 } |
|
455 |
|
456 EXPORT_C void CRYPTO_set_dynlock_destroy_callback(void (*func) |
|
457 (struct CRYPTO_dynlock_value *l, const char *file, int line)) |
|
458 { |
|
459 dynlock_destroy_callback=func; |
|
460 } |
|
461 |
|
462 |
|
463 EXPORT_C void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, |
|
464 int line) |
|
465 { |
|
466 return(locking_callback); |
|
467 } |
|
468 |
|
469 EXPORT_C int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, |
|
470 const char *file,int line) |
|
471 { |
|
472 return(add_lock_callback); |
|
473 } |
|
474 |
|
475 EXPORT_C void CRYPTO_set_locking_callback(void (*func)(int mode,int type, |
|
476 const char *file,int line)) |
|
477 { |
|
478 locking_callback=func; |
|
479 } |
|
480 |
|
481 EXPORT_C void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, |
|
482 const char *file,int line)) |
|
483 { |
|
484 add_lock_callback=func; |
|
485 } |
|
486 |
|
487 EXPORT_C unsigned long (*CRYPTO_get_id_callback(void))(void) |
|
488 { |
|
489 return(id_callback); |
|
490 } |
|
491 |
|
492 EXPORT_C void CRYPTO_set_id_callback(unsigned long (*func)(void)) |
|
493 { |
|
494 id_callback=func; |
|
495 } |
|
496 |
|
497 EXPORT_C unsigned long CRYPTO_thread_id(void) |
|
498 { |
|
499 unsigned long ret=0; |
|
500 |
|
501 if (id_callback == NULL) |
|
502 { |
|
503 #ifdef OPENSSL_SYS_WIN16 |
|
504 ret=(unsigned long)GetCurrentTask(); |
|
505 #elif defined(OPENSSL_SYS_WIN32) |
|
506 ret=(unsigned long)GetCurrentThreadId(); |
|
507 #elif defined(GETPID_IS_MEANINGLESS) |
|
508 ret=1L; |
|
509 #else |
|
510 //ret=(unsigned long)getpid(); |
|
511 //ret=(unsigned long)getpid(; |
|
512 #endif |
|
513 } |
|
514 else |
|
515 ret=id_callback(); |
|
516 return(ret); |
|
517 } |
|
518 |
|
519 EXPORT_C void CRYPTO_lock(int mode, int type, const char *file, int line) |
|
520 { |
|
521 #ifdef LOCK_DEBUG |
|
522 { |
|
523 char *rw_text,*operation_text; |
|
524 |
|
525 if (mode & CRYPTO_LOCK) |
|
526 operation_text="lock "; |
|
527 else if (mode & CRYPTO_UNLOCK) |
|
528 operation_text="unlock"; |
|
529 else |
|
530 operation_text="ERROR "; |
|
531 |
|
532 if (mode & CRYPTO_READ) |
|
533 rw_text="r"; |
|
534 else if (mode & CRYPTO_WRITE) |
|
535 rw_text="w"; |
|
536 else |
|
537 rw_text="ERROR"; |
|
538 |
|
539 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", |
|
540 CRYPTO_thread_id(), rw_text, operation_text, |
|
541 CRYPTO_get_lock_name(type), file, line); |
|
542 } |
|
543 #endif |
|
544 if (type < 0) |
|
545 { |
|
546 if (dynlock_lock_callback != NULL) |
|
547 { |
|
548 struct CRYPTO_dynlock_value *pointer |
|
549 = CRYPTO_get_dynlock_value(type); |
|
550 |
|
551 OPENSSL_assert(pointer != NULL); |
|
552 |
|
553 dynlock_lock_callback(mode, pointer, file, line); |
|
554 |
|
555 CRYPTO_destroy_dynlockid(type); |
|
556 } |
|
557 } |
|
558 else |
|
559 if (locking_callback != NULL) |
|
560 locking_callback(mode,type,file,line); |
|
561 } |
|
562 |
|
563 EXPORT_C int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, |
|
564 int line) |
|
565 { |
|
566 int ret = 0; |
|
567 |
|
568 if (add_lock_callback != NULL) |
|
569 { |
|
570 #ifdef LOCK_DEBUG |
|
571 int before= *pointer; |
|
572 #endif |
|
573 |
|
574 ret=add_lock_callback(pointer,amount,type,file,line); |
|
575 #ifdef LOCK_DEBUG |
|
576 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", |
|
577 CRYPTO_thread_id(), |
|
578 before,amount,ret, |
|
579 CRYPTO_get_lock_name(type), |
|
580 file,line); |
|
581 #endif |
|
582 } |
|
583 else |
|
584 { |
|
585 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line); |
|
586 |
|
587 ret= *pointer+amount; |
|
588 #ifdef LOCK_DEBUG |
|
589 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", |
|
590 CRYPTO_thread_id(), |
|
591 *pointer,amount,ret, |
|
592 CRYPTO_get_lock_name(type), |
|
593 file,line); |
|
594 #endif |
|
595 *pointer=ret; |
|
596 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); |
|
597 } |
|
598 return(ret); |
|
599 } |
|
600 |
|
601 EXPORT_C const char *CRYPTO_get_lock_name(int type) |
|
602 { |
|
603 if (type < 0) |
|
604 return("dynamic"); |
|
605 else if (type < CRYPTO_NUM_LOCKS) |
|
606 return(lock_names[type]); |
|
607 else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks)) |
|
608 return("ERROR"); |
|
609 else |
|
610 return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS)); |
|
611 } |
|
612 |
|
613 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ |
|
614 defined(__INTEL__) || \ |
|
615 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) |
|
616 |
|
617 unsigned long OPENSSL_ia32cap_P=0; |
|
618 EXPORT_C unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; } |
|
619 |
|
620 #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) |
|
621 #define OPENSSL_CPUID_SETUP |
|
622 EXPORT_C void OPENSSL_cpuid_setup(void) |
|
623 { static int trigger=0; |
|
624 unsigned long OPENSSL_ia32_cpuid(void); |
|
625 char *env; |
|
626 |
|
627 if (trigger) return; |
|
628 |
|
629 trigger=1; |
|
630 if ((env=getenv("OPENSSL_ia32cap"))) |
|
631 OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10); |
|
632 else |
|
633 OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10); |
|
634 /* |
|
635 * |(1<<10) sets a reserved bit to signal that variable |
|
636 * was initialized already... This is to avoid interference |
|
637 * with cpuid snippets in ELF .init segment. |
|
638 */ |
|
639 } |
|
640 #endif |
|
641 |
|
642 #else |
|
643 EXPORT_C unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; } |
|
644 #endif |
|
645 int OPENSSL_NONPIC_relocated = 0; |
|
646 #if !defined(OPENSSL_CPUID_SETUP) |
|
647 EXPORT_C void OPENSSL_cpuid_setup(void) {} |
|
648 #endif |
|
649 |
|
650 #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) |
|
651 #ifdef __CYGWIN__ |
|
652 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ |
|
653 #include <windows.h> |
|
654 #endif |
|
655 |
|
656 /* All we really need to do is remove the 'error' state when a thread |
|
657 * detaches */ |
|
658 |
|
659 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, |
|
660 LPVOID lpvReserved) |
|
661 { |
|
662 switch(fdwReason) |
|
663 { |
|
664 case DLL_PROCESS_ATTACH: |
|
665 OPENSSL_cpuid_setup(); |
|
666 #if defined(_WIN32_WINNT) |
|
667 { |
|
668 IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL; |
|
669 IMAGE_NT_HEADERS *nt_headers; |
|
670 |
|
671 if (dos_header->e_magic==IMAGE_DOS_SIGNATURE) |
|
672 { |
|
673 nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header |
|
674 + dos_header->e_lfanew); |
|
675 if (nt_headers->Signature==IMAGE_NT_SIGNATURE && |
|
676 hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase)) |
|
677 OPENSSL_NONPIC_relocated=1; |
|
678 } |
|
679 } |
|
680 #endif |
|
681 break; |
|
682 case DLL_THREAD_ATTACH: |
|
683 break; |
|
684 case DLL_THREAD_DETACH: |
|
685 ERR_remove_state(0); |
|
686 break; |
|
687 case DLL_PROCESS_DETACH: |
|
688 break; |
|
689 } |
|
690 return(TRUE); |
|
691 } |
|
692 #endif |
|
693 |
|
694 #if defined(_WIN32) && !defined(__CYGWIN__)&& !defined(SYMBIAN) |
|
695 #include <tchar.h> |
|
696 |
|
697 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 |
|
698 EXPORT_C int OPENSSL_isservice(void) |
|
699 { HWINSTA h; |
|
700 DWORD len; |
|
701 WCHAR *name; |
|
702 |
|
703 (void)GetDesktopWindow(); /* return value is ignored */ |
|
704 |
|
705 h = GetProcessWindowStation(); |
|
706 if (h==NULL) return -1; |
|
707 |
|
708 if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) || |
|
709 GetLastError() != ERROR_INSUFFICIENT_BUFFER) |
|
710 return -1; |
|
711 |
|
712 if (len>512) return -1; /* paranoia */ |
|
713 len++,len&=~1; /* paranoia */ |
|
714 #ifdef _MSC_VER |
|
715 name=(WCHAR *)_alloca(len+sizeof(WCHAR)); |
|
716 #else |
|
717 name=(WCHAR *)alloca(len+sizeof(WCHAR)); |
|
718 #endif |
|
719 if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len)) |
|
720 return -1; |
|
721 |
|
722 len++,len&=~1; /* paranoia */ |
|
723 name[len/sizeof(WCHAR)]=L'\0'; /* paranoia */ |
|
724 #if 1 |
|
725 /* This doesn't cover "interactive" services [working with real |
|
726 * WinSta0's] nor programs started non-interactively by Task |
|
727 * Scheduler [those are working with SAWinSta]. */ |
|
728 if (wcsstr(name,L"Service-0x")) return 1; |
|
729 #else |
|
730 /* This covers all non-interactive programs such as services. */ |
|
731 if (!wcsstr(name,L"WinSta0")) return 1; |
|
732 #endif |
|
733 else return 0; |
|
734 } |
|
735 #else |
|
736 EXPORT_C int OPENSSL_isservice(void) { return 0; } |
|
737 #endif |
|
738 |
|
739 EXPORT_C void OPENSSL_showfatal (const char *fmta,...) |
|
740 { va_list ap; |
|
741 #ifndef SYMBIAN |
|
742 TCHAR buf[256]; |
|
743 #else |
|
744 TCHAR buf[100]; |
|
745 #endif |
|
746 const TCHAR *fmt; |
|
747 #ifdef STD_ERROR_HANDLE /* what a dirty trick! */ |
|
748 HANDLE h; |
|
749 |
|
750 if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL && |
|
751 GetFileType(h)!=FILE_TYPE_UNKNOWN) |
|
752 { /* must be console application */ |
|
753 va_start (ap,fmta); |
|
754 vfprintf (stderr,fmta,ap); |
|
755 va_end (ap); |
|
756 return; |
|
757 } |
|
758 #endif |
|
759 |
|
760 if (sizeof(TCHAR)==sizeof(char)) |
|
761 fmt=(const TCHAR *)fmta; |
|
762 else do |
|
763 { int keepgoing; |
|
764 size_t len_0=strlen(fmta)+1,i; |
|
765 WCHAR *fmtw; |
|
766 |
|
767 #ifdef _MSC_VER |
|
768 fmtw = (WCHAR *)_alloca (len_0*sizeof(WCHAR)); |
|
769 #else |
|
770 fmtw = (WCHAR *)alloca (len_0*sizeof(WCHAR)); |
|
771 #endif |
|
772 if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; } |
|
773 |
|
774 #ifndef OPENSSL_NO_MULTIBYTE |
|
775 if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0)) |
|
776 #endif |
|
777 for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i]; |
|
778 |
|
779 for (i=0;i<len_0;i++) |
|
780 { if (fmtw[i]==L'%') do |
|
781 { keepgoing=0; |
|
782 switch (fmtw[i+1]) |
|
783 { case L'0': case L'1': case L'2': case L'3': case L'4': |
|
784 case L'5': case L'6': case L'7': case L'8': case L'9': |
|
785 case L'.': case L'*': |
|
786 case L'-': i++; keepgoing=1; break; |
|
787 case L's': fmtw[i+1]=L'S'; break; |
|
788 case L'S': fmtw[i+1]=L's'; break; |
|
789 case L'c': fmtw[i+1]=L'C'; break; |
|
790 case L'C': fmtw[i+1]=L'c'; break; |
|
791 } |
|
792 } while (keepgoing); |
|
793 } |
|
794 fmt = (const TCHAR *)fmtw; |
|
795 } while (0); |
|
796 |
|
797 va_start (ap,fmta); |
|
798 _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap); |
|
799 buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0'); |
|
800 va_end (ap); |
|
801 |
|
802 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 |
|
803 /* this -------------v--- guards NT-specific calls */ |
|
804 if (GetVersion() < 0x80000000 && OPENSSL_isservice()) |
|
805 { HANDLE h = RegisterEventSource(0,_T("OPENSSL")); |
|
806 const TCHAR *pmsg=buf; |
|
807 ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0); |
|
808 DeregisterEventSource(h); |
|
809 } |
|
810 else |
|
811 #endif |
|
812 MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP); |
|
813 } |
|
814 #else |
|
815 EXPORT_C void OPENSSL_showfatal (const char *fmta,...) |
|
816 { va_list ap; |
|
817 |
|
818 va_start (ap,fmta); |
|
819 vfprintf (stderr,fmta,ap); |
|
820 va_end (ap); |
|
821 } |
|
822 EXPORT_C int OPENSSL_isservice (void) { return 0; } |
|
823 #endif |
|
824 |
|
825 EXPORT_C void OpenSSLDie(const char *file,int line,const char *assertion) |
|
826 { |
|
827 OPENSSL_showfatal( |
|
828 "%s(%d): OpenSSL internal error, assertion failed: %s\n", |
|
829 file,line,assertion); |
|
830 abort(); |
|
831 } |
|
832 |
|
833 EXPORT_C void *OPENSSL_stderr(void) { return stderr; } |
|
834 |