OLD | NEW |
1 /* crypto/cryptlib.c */ | 1 /* crypto/cryptlib.c */ |
2 /* ==================================================================== | 2 /* ==================================================================== |
3 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | 3 * Copyright (c) 1998-2006 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 |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * | 11 * |
12 * 2. Redistributions in binary form must reproduce the above copyright | 12 * 2. Redistributions in binary form must reproduce the above copyright |
13 * notice, this list of conditions and the following disclaimer in | 13 * notice, this list of conditions and the following disclaimer in |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. | 114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. |
115 */ | 115 */ |
116 | 116 |
117 #include "cryptlib.h" | 117 #include "cryptlib.h" |
118 #include <openssl/safestack.h> | 118 #include <openssl/safestack.h> |
119 | 119 |
120 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) | 120 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) |
121 static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ | 121 static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ |
122 #endif | 122 #endif |
123 | 123 |
| 124 DECLARE_STACK_OF(CRYPTO_dynlock) |
| 125 |
| 126 /* real #defines in crypto.h, keep these upto date */ |
| 127 static const char* const lock_names[CRYPTO_NUM_LOCKS] = |
| 128 { |
| 129 "<<ERROR>>", |
| 130 "err", |
| 131 "ex_data", |
| 132 "x509", |
| 133 "x509_info", |
| 134 "x509_pkey", |
| 135 "x509_crl", |
| 136 "x509_req", |
| 137 "dsa", |
| 138 "rsa", |
| 139 "evp_pkey", |
| 140 "x509_store", |
| 141 "ssl_ctx", |
| 142 "ssl_cert", |
| 143 "ssl_session", |
| 144 "ssl_sess_cert", |
| 145 "ssl", |
| 146 "ssl_method", |
| 147 "rand", |
| 148 "rand2", |
| 149 "debug_malloc", |
| 150 "BIO", |
| 151 "gethostbyname", |
| 152 "getservbyname", |
| 153 "readdir", |
| 154 "RSA_blinding", |
| 155 "dh", |
| 156 "debug_malloc2", |
| 157 "dso", |
| 158 "dynlock", |
| 159 "engine", |
| 160 "ui", |
| 161 "ecdsa", |
| 162 "ec", |
| 163 "ecdh", |
| 164 "bn", |
| 165 "ec_pre_comp", |
| 166 "store", |
| 167 "comp", |
| 168 "fips", |
| 169 "fips2", |
| 170 #if CRYPTO_NUM_LOCKS != 41 |
| 171 # error "Inconsistency between crypto.h and cryptlib.c" |
| 172 #endif |
| 173 }; |
| 174 |
| 175 /* This is for applications to allocate new type names in the non-dynamic |
| 176 array of lock names. These are numbered with positive numbers. */ |
| 177 static STACK_OF(OPENSSL_STRING) *app_locks=NULL; |
| 178 |
| 179 /* For applications that want a more dynamic way of handling threads, the |
| 180 following stack is used. These are externally numbered with negative |
| 181 numbers. */ |
| 182 static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; |
| 183 |
| 184 |
124 static void (MS_FAR *locking_callback)(int mode,int type, | 185 static void (MS_FAR *locking_callback)(int mode,int type, |
125 » const char *file,int line)=NULL; | 186 » const char *file,int line)=0; |
126 static int (MS_FAR *add_lock_callback)(int *pointer,int amount, | 187 static int (MS_FAR *add_lock_callback)(int *pointer,int amount, |
127 » int type,const char *file,int line)=NULL; | 188 » int type,const char *file,int line)=0; |
128 static unsigned long (MS_FAR *id_callback)(void)=NULL; | 189 #ifndef OPENSSL_NO_DEPRECATED |
| 190 static unsigned long (MS_FAR *id_callback)(void)=0; |
| 191 #endif |
| 192 static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0; |
| 193 static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) |
| 194 » (const char *file,int line)=0; |
| 195 static void (MS_FAR *dynlock_lock_callback)(int mode, |
| 196 » struct CRYPTO_dynlock_value *l, const char *file,int line)=0; |
| 197 static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, |
| 198 » const char *file,int line)=0; |
| 199 |
| 200 int CRYPTO_get_new_lockid(char *name) |
| 201 » { |
| 202 » char *str; |
| 203 » int i; |
| 204 |
| 205 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) |
| 206 » /* A hack to make Visual C++ 5.0 work correctly when linking as |
| 207 » * a DLL using /MT. Without this, the application cannot use |
| 208 » * any floating point printf's. |
| 209 » * It also seems to be needed for Visual C 1.5 (win16) */ |
| 210 » SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; |
| 211 #endif |
| 212 |
| 213 » if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) ==
NULL)) |
| 214 » » { |
| 215 » » CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); |
| 216 » » return(0); |
| 217 » » } |
| 218 » if ((str=BUF_strdup(name)) == NULL) |
| 219 » » { |
| 220 » » CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE); |
| 221 » » return(0); |
| 222 » » } |
| 223 » i=sk_OPENSSL_STRING_push(app_locks,str); |
| 224 » if (!i) |
| 225 » » OPENSSL_free(str); |
| 226 » else |
| 227 » » i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */ |
| 228 » return(i); |
| 229 » } |
129 | 230 |
130 int CRYPTO_num_locks(void) | 231 int CRYPTO_num_locks(void) |
131 { | 232 { |
132 return CRYPTO_NUM_LOCKS; | 233 return CRYPTO_NUM_LOCKS; |
133 } | 234 } |
134 | 235 |
| 236 int CRYPTO_get_new_dynlockid(void) |
| 237 { |
| 238 int i = 0; |
| 239 CRYPTO_dynlock *pointer = NULL; |
| 240 |
| 241 if (dynlock_create_callback == NULL) |
| 242 { |
| 243 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_
CREATE_CALLBACK); |
| 244 return(0); |
| 245 } |
| 246 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
| 247 if ((dyn_locks == NULL) |
| 248 && ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL)) |
| 249 { |
| 250 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
| 251 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE
); |
| 252 return(0); |
| 253 } |
| 254 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
| 255 |
| 256 pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock)); |
| 257 if (pointer == NULL) |
| 258 { |
| 259 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE
); |
| 260 return(0); |
| 261 } |
| 262 pointer->references = 1; |
| 263 pointer->data = dynlock_create_callback(__FILE__,__LINE__); |
| 264 if (pointer->data == NULL) |
| 265 { |
| 266 OPENSSL_free(pointer); |
| 267 CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE
); |
| 268 return(0); |
| 269 } |
| 270 |
| 271 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
| 272 /* First, try to find an existing empty slot */ |
| 273 i=sk_CRYPTO_dynlock_find(dyn_locks,NULL); |
| 274 /* If there was none, push, thereby creating a new one */ |
| 275 if (i == -1) |
| 276 /* Since sk_push() returns the number of items on the |
| 277 stack, not the location of the pushed item, we need |
| 278 to transform the returned number into a position, |
| 279 by decreasing it. */ |
| 280 i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1; |
| 281 else |
| 282 /* If we found a place with a NULL pointer, put our pointer |
| 283 in it. */ |
| 284 (void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer); |
| 285 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
| 286 |
| 287 if (i == -1) |
| 288 { |
| 289 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); |
| 290 OPENSSL_free(pointer); |
| 291 } |
| 292 else |
| 293 i += 1; /* to avoid 0 */ |
| 294 return -i; |
| 295 } |
| 296 |
| 297 void CRYPTO_destroy_dynlockid(int i) |
| 298 { |
| 299 CRYPTO_dynlock *pointer = NULL; |
| 300 if (i) |
| 301 i = -i-1; |
| 302 if (dynlock_destroy_callback == NULL) |
| 303 return; |
| 304 |
| 305 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
| 306 |
| 307 if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) |
| 308 { |
| 309 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
| 310 return; |
| 311 } |
| 312 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); |
| 313 if (pointer != NULL) |
| 314 { |
| 315 --pointer->references; |
| 316 #ifdef REF_CHECK |
| 317 if (pointer->references < 0) |
| 318 { |
| 319 fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference
count\n"); |
| 320 abort(); |
| 321 } |
| 322 else |
| 323 #endif |
| 324 if (pointer->references <= 0) |
| 325 { |
| 326 (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); |
| 327 } |
| 328 else |
| 329 pointer = NULL; |
| 330 } |
| 331 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
| 332 |
| 333 if (pointer) |
| 334 { |
| 335 dynlock_destroy_callback(pointer->data,__FILE__,__LINE__); |
| 336 OPENSSL_free(pointer); |
| 337 } |
| 338 } |
| 339 |
| 340 struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) |
| 341 { |
| 342 CRYPTO_dynlock *pointer = NULL; |
| 343 if (i) |
| 344 i = -i-1; |
| 345 |
| 346 CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); |
| 347 |
| 348 if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) |
| 349 pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); |
| 350 if (pointer) |
| 351 pointer->references++; |
| 352 |
| 353 CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); |
| 354 |
| 355 if (pointer) |
| 356 return pointer->data; |
| 357 return NULL; |
| 358 } |
| 359 |
| 360 struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) |
| 361 (const char *file,int line) |
| 362 { |
| 363 return(dynlock_create_callback); |
| 364 } |
| 365 |
| 366 void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, |
| 367 struct CRYPTO_dynlock_value *l, const char *file,int line) |
| 368 { |
| 369 return(dynlock_lock_callback); |
| 370 } |
| 371 |
| 372 void (*CRYPTO_get_dynlock_destroy_callback(void)) |
| 373 (struct CRYPTO_dynlock_value *l, const char *file,int line) |
| 374 { |
| 375 return(dynlock_destroy_callback); |
| 376 } |
| 377 |
| 378 void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) |
| 379 (const char *file, int line)) |
| 380 { |
| 381 dynlock_create_callback=func; |
| 382 } |
| 383 |
| 384 void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode, |
| 385 struct CRYPTO_dynlock_value *l, const char *file, int line)) |
| 386 { |
| 387 dynlock_lock_callback=func; |
| 388 } |
| 389 |
| 390 void CRYPTO_set_dynlock_destroy_callback(void (*func) |
| 391 (struct CRYPTO_dynlock_value *l, const char *file, int line)) |
| 392 { |
| 393 dynlock_destroy_callback=func; |
| 394 } |
| 395 |
| 396 |
135 void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, | 397 void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, |
136 int line) | 398 int line) |
137 { | 399 { |
138 return(locking_callback); | 400 return(locking_callback); |
139 } | 401 } |
140 | 402 |
141 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, | 403 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, |
142 const char *file,int line) | 404 const char *file,int line) |
143 { | 405 { |
144 return(add_lock_callback); | 406 return(add_lock_callback); |
145 } | 407 } |
146 | 408 |
147 void CRYPTO_set_locking_callback(void (*func)(int mode,int type, | 409 void CRYPTO_set_locking_callback(void (*func)(int mode,int type, |
148 const char *file,int line)) | 410 const char *file,int line)) |
149 { | 411 { |
150 locking_callback=func; | 412 locking_callback=func; |
151 } | 413 } |
152 | 414 |
153 void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, | 415 void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, |
154 const char *file,int line)) | 416 const char *file,int line)) |
155 { | 417 { |
156 add_lock_callback=func; | 418 add_lock_callback=func; |
157 } | 419 } |
158 | 420 |
| 421 /* the memset() here and in set_pointer() seem overkill, but for the sake of |
| 422 * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two |
| 423 * "equal" THREADID structs to not be memcmp()-identical. */ |
| 424 void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) |
| 425 { |
| 426 memset(id, 0, sizeof(*id)); |
| 427 id->val = val; |
| 428 } |
| 429 |
| 430 static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 }; |
| 431 void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) |
| 432 { |
| 433 unsigned char *dest = (void *)&id->val; |
| 434 unsigned int accum = 0; |
| 435 unsigned char dnum = sizeof(id->val); |
| 436 |
| 437 memset(id, 0, sizeof(*id)); |
| 438 id->ptr = ptr; |
| 439 if (sizeof(id->val) >= sizeof(id->ptr)) |
| 440 { |
| 441 /* 'ptr' can be embedded in 'val' without loss of uniqueness */ |
| 442 id->val = (unsigned long)id->ptr; |
| 443 return; |
| 444 } |
| 445 /* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a |
| 446 * linear function over the bytes in 'ptr', the co-efficients of which |
| 447 * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - |
| 448 * the starting prime for the sequence varies for each byte of 'val' |
| 449 * (unique polynomials unless pointers are >64-bit). For added spice, |
| 450 * the totals accumulate rather than restarting from zero, and the index |
| 451 * of the 'val' byte is added each time (position dependence). If I was |
| 452 * a black-belt, I'd scan big-endian pointers in reverse to give |
| 453 * low-order bits more play, but this isn't crypto and I'd prefer nobody |
| 454 * mistake it as such. Plus I'm lazy. */ |
| 455 while (dnum--) |
| 456 { |
| 457 const unsigned char *src = (void *)&id->ptr; |
| 458 unsigned char snum = sizeof(id->ptr); |
| 459 while (snum--) |
| 460 accum += *(src++) * hash_coeffs[(snum + dnum) & 7]; |
| 461 accum += dnum; |
| 462 *(dest++) = accum & 255; |
| 463 } |
| 464 } |
| 465 |
| 466 int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) |
| 467 { |
| 468 if (threadid_callback) |
| 469 return 0; |
| 470 threadid_callback = func; |
| 471 return 1; |
| 472 } |
| 473 |
| 474 void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *) |
| 475 { |
| 476 return threadid_callback; |
| 477 } |
| 478 |
| 479 void CRYPTO_THREADID_current(CRYPTO_THREADID *id) |
| 480 { |
| 481 if (threadid_callback) |
| 482 { |
| 483 threadid_callback(id); |
| 484 return; |
| 485 } |
| 486 #ifndef OPENSSL_NO_DEPRECATED |
| 487 /* If the deprecated callback was set, fall back to that */ |
| 488 if (id_callback) |
| 489 { |
| 490 CRYPTO_THREADID_set_numeric(id, id_callback()); |
| 491 return; |
| 492 } |
| 493 #endif |
| 494 /* Else pick a backup */ |
| 495 #ifdef OPENSSL_SYS_WIN16 |
| 496 CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask()); |
| 497 #elif defined(OPENSSL_SYS_WIN32) |
| 498 CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId()); |
| 499 #elif defined(OPENSSL_SYS_BEOS) |
| 500 CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL)); |
| 501 #else |
| 502 /* For everything else, default to using the address of 'errno' */ |
| 503 CRYPTO_THREADID_set_pointer(id, &errno); |
| 504 #endif |
| 505 } |
| 506 |
| 507 int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) |
| 508 { |
| 509 return memcmp(a, b, sizeof(*a)); |
| 510 } |
| 511 |
| 512 void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) |
| 513 { |
| 514 memcpy(dest, src, sizeof(*src)); |
| 515 } |
| 516 |
| 517 unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) |
| 518 { |
| 519 return id->val; |
| 520 } |
| 521 |
| 522 #ifndef OPENSSL_NO_DEPRECATED |
159 unsigned long (*CRYPTO_get_id_callback(void))(void) | 523 unsigned long (*CRYPTO_get_id_callback(void))(void) |
160 { | 524 { |
161 return(id_callback); | 525 return(id_callback); |
162 } | 526 } |
163 | 527 |
164 void CRYPTO_set_id_callback(unsigned long (*func)(void)) | 528 void CRYPTO_set_id_callback(unsigned long (*func)(void)) |
165 { | 529 { |
166 id_callback=func; | 530 id_callback=func; |
167 } | 531 } |
168 | 532 |
169 unsigned long CRYPTO_thread_id(void) | 533 unsigned long CRYPTO_thread_id(void) |
170 { | 534 { |
171 unsigned long ret=0; | 535 unsigned long ret=0; |
172 | 536 |
173 if (id_callback == NULL) | 537 if (id_callback == NULL) |
174 { | 538 { |
175 #ifdef OPENSSL_SYS_WIN16 | 539 #ifdef OPENSSL_SYS_WIN16 |
176 ret=(unsigned long)GetCurrentTask(); | 540 ret=(unsigned long)GetCurrentTask(); |
177 #elif defined(OPENSSL_SYS_WIN32) | 541 #elif defined(OPENSSL_SYS_WIN32) |
178 ret=(unsigned long)GetCurrentThreadId(); | 542 ret=(unsigned long)GetCurrentThreadId(); |
179 #elif defined(GETPID_IS_MEANINGLESS) | 543 #elif defined(GETPID_IS_MEANINGLESS) |
180 ret=1L; | 544 ret=1L; |
| 545 #elif defined(OPENSSL_SYS_BEOS) |
| 546 ret=(unsigned long)find_thread(NULL); |
181 #else | 547 #else |
182 ret=(unsigned long)getpid(); | 548 ret=(unsigned long)getpid(); |
183 #endif | 549 #endif |
184 } | 550 } |
185 else | 551 else |
186 ret=id_callback(); | 552 ret=id_callback(); |
187 return(ret); | 553 return(ret); |
188 } | 554 } |
189 | 555 #endif |
190 static void (*do_dynlock_cb)(int mode, int type, const char *file, int line); | |
191 | |
192 void int_CRYPTO_set_do_dynlock_callback( | |
193 » void (*dyn_cb)(int mode, int type, const char *file, int line)) | |
194 » { | |
195 » do_dynlock_cb = dyn_cb; | |
196 » } | |
197 | 556 |
198 void CRYPTO_lock(int mode, int type, const char *file, int line) | 557 void CRYPTO_lock(int mode, int type, const char *file, int line) |
199 { | 558 { |
200 #ifdef LOCK_DEBUG | 559 #ifdef LOCK_DEBUG |
201 { | 560 { |
| 561 CRYPTO_THREADID id; |
202 char *rw_text,*operation_text; | 562 char *rw_text,*operation_text; |
203 | 563 |
204 if (mode & CRYPTO_LOCK) | 564 if (mode & CRYPTO_LOCK) |
205 operation_text="lock "; | 565 operation_text="lock "; |
206 else if (mode & CRYPTO_UNLOCK) | 566 else if (mode & CRYPTO_UNLOCK) |
207 operation_text="unlock"; | 567 operation_text="unlock"; |
208 else | 568 else |
209 operation_text="ERROR "; | 569 operation_text="ERROR "; |
210 | 570 |
211 if (mode & CRYPTO_READ) | 571 if (mode & CRYPTO_READ) |
212 rw_text="r"; | 572 rw_text="r"; |
213 else if (mode & CRYPTO_WRITE) | 573 else if (mode & CRYPTO_WRITE) |
214 rw_text="w"; | 574 rw_text="w"; |
215 else | 575 else |
216 rw_text="ERROR"; | 576 rw_text="ERROR"; |
217 | 577 |
| 578 CRYPTO_THREADID_current(&id); |
218 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", | 579 fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", |
219 » » » CRYPTO_thread_id(), rw_text, operation_text, | 580 » » » CRYPTO_THREADID_hash(&id), rw_text, operation_text, |
220 CRYPTO_get_lock_name(type), file, line); | 581 CRYPTO_get_lock_name(type), file, line); |
221 } | 582 } |
222 #endif | 583 #endif |
223 if (type < 0) | 584 if (type < 0) |
224 { | 585 { |
225 » » if (do_dynlock_cb) | 586 » » if (dynlock_lock_callback != NULL) |
226 » » » do_dynlock_cb(mode, type, file, line); | 587 » » » { |
| 588 » » » struct CRYPTO_dynlock_value *pointer |
| 589 » » » » = CRYPTO_get_dynlock_value(type); |
| 590 |
| 591 » » » OPENSSL_assert(pointer != NULL); |
| 592 |
| 593 » » » dynlock_lock_callback(mode, pointer, file, line); |
| 594 |
| 595 » » » CRYPTO_destroy_dynlockid(type); |
| 596 » » » } |
227 } | 597 } |
228 else | 598 else |
229 if (locking_callback != NULL) | 599 if (locking_callback != NULL) |
230 locking_callback(mode,type,file,line); | 600 locking_callback(mode,type,file,line); |
231 } | 601 } |
232 | 602 |
233 int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, | 603 int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, |
234 int line) | 604 int line) |
235 { | 605 { |
236 int ret = 0; | 606 int ret = 0; |
237 | 607 |
238 if (add_lock_callback != NULL) | 608 if (add_lock_callback != NULL) |
239 { | 609 { |
240 #ifdef LOCK_DEBUG | 610 #ifdef LOCK_DEBUG |
241 int before= *pointer; | 611 int before= *pointer; |
242 #endif | 612 #endif |
243 | 613 |
244 ret=add_lock_callback(pointer,amount,type,file,line); | 614 ret=add_lock_callback(pointer,amount,type,file,line); |
245 #ifdef LOCK_DEBUG | 615 #ifdef LOCK_DEBUG |
| 616 { |
| 617 CRYPTO_THREADID id; |
| 618 CRYPTO_THREADID_current(&id); |
246 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", | 619 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", |
247 » » » CRYPTO_thread_id(), | 620 » » » CRYPTO_THREADID_hash(&id), before,amount,ret, |
248 » » » before,amount,ret, | |
249 CRYPTO_get_lock_name(type), | 621 CRYPTO_get_lock_name(type), |
250 file,line); | 622 file,line); |
| 623 } |
251 #endif | 624 #endif |
252 } | 625 } |
253 else | 626 else |
254 { | 627 { |
255 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line); | 628 CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line); |
256 | 629 |
257 ret= *pointer+amount; | 630 ret= *pointer+amount; |
258 #ifdef LOCK_DEBUG | 631 #ifdef LOCK_DEBUG |
| 632 { |
| 633 CRYPTO_THREADID id; |
| 634 CRYPTO_THREADID_current(&id); |
259 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", | 635 fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", |
260 » » » CRYPTO_thread_id(), | 636 » » » CRYPTO_THREADID_hash(&id), |
261 *pointer,amount,ret, | 637 *pointer,amount,ret, |
262 CRYPTO_get_lock_name(type), | 638 CRYPTO_get_lock_name(type), |
263 file,line); | 639 file,line); |
| 640 } |
264 #endif | 641 #endif |
265 *pointer=ret; | 642 *pointer=ret; |
266 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); | 643 CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); |
267 } | 644 } |
268 return(ret); | 645 return(ret); |
269 } | 646 } |
270 | 647 |
| 648 const char *CRYPTO_get_lock_name(int type) |
| 649 { |
| 650 if (type < 0) |
| 651 return("dynamic"); |
| 652 else if (type < CRYPTO_NUM_LOCKS) |
| 653 return(lock_names[type]); |
| 654 else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) |
| 655 return("ERROR"); |
| 656 else |
| 657 return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS))
; |
| 658 } |
| 659 |
271 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ | 660 #if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ |
272 defined(__INTEL__) || \ | 661 defined(__INTEL__) || \ |
273 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined
(_M_X64) | 662 defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined
(_M_X64) |
274 | 663 |
275 unsigned long OPENSSL_ia32cap_P=0; | 664 unsigned long OPENSSL_ia32cap_P=0; |
276 unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; } | 665 unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; } |
277 | 666 |
278 #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY
) | 667 #if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY
) |
279 #define OPENSSL_CPUID_SETUP | 668 #define OPENSSL_CPUID_SETUP |
280 void OPENSSL_cpuid_setup(void) | 669 void OPENSSL_cpuid_setup(void) |
(...skipping 18 matching lines...) Expand all Loading... |
299 | 688 |
300 #else | 689 #else |
301 unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; } | 690 unsigned long *OPENSSL_ia32cap_loc(void) { return NULL; } |
302 #endif | 691 #endif |
303 int OPENSSL_NONPIC_relocated = 0; | 692 int OPENSSL_NONPIC_relocated = 0; |
304 #if !defined(OPENSSL_CPUID_SETUP) | 693 #if !defined(OPENSSL_CPUID_SETUP) |
305 void OPENSSL_cpuid_setup(void) {} | 694 void OPENSSL_cpuid_setup(void) {} |
306 #endif | 695 #endif |
307 | 696 |
308 #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) | 697 #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) |
309 | |
310 #ifdef OPENSSL_FIPS | |
311 | |
312 #include <tlhelp32.h> | |
313 #if defined(__GNUC__) && __GNUC__>=2 | |
314 static int DllInit(void) __attribute__((constructor)); | |
315 #elif defined(_MSC_VER) | |
316 static int DllInit(void); | |
317 # ifdef _WIN64 | |
318 # pragma section(".CRT$XCU",read) | |
319 __declspec(allocate(".CRT$XCU")) | |
320 # else | |
321 # pragma data_seg(".CRT$XCU") | |
322 # endif | |
323 static int (*p)(void) = DllInit; | |
324 # pragma data_seg() | |
325 #endif | |
326 | |
327 static int DllInit(void) | |
328 { | |
329 #if defined(_WIN32_WINNT) | |
330 union { int(*f)(void); BYTE *p; } t = { DllInit }; | |
331 HANDLE hModuleSnap = INVALID_HANDLE_VALUE; | |
332 IMAGE_DOS_HEADER *dos_header; | |
333 IMAGE_NT_HEADERS *nt_headers; | |
334 MODULEENTRY32 me32 = {sizeof(me32)}; | |
335 | |
336 hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0); | |
337 if (hModuleSnap != INVALID_HANDLE_VALUE && | |
338 Module32First(hModuleSnap,&me32)) do | |
339 { | |
340 if (t.p >= me32.modBaseAddr && | |
341 t.p < me32.modBaseAddr+me32.modBaseSize) | |
342 { | |
343 dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr; | |
344 if (dos_header->e_magic==IMAGE_DOS_SIGNATURE) | |
345 { | |
346 nt_headers=(IMAGE_NT_HEADERS *) | |
347 ((BYTE *)dos_header+dos_header->e_lfanew
); | |
348 if (nt_headers->Signature==IMAGE_NT_SIGNATURE && | |
349 me32.modBaseAddr!=(BYTE*)nt_headers->Optiona
lHeader.ImageBase) | |
350 OPENSSL_NONPIC_relocated=1; | |
351 } | |
352 break; | |
353 } | |
354 } while (Module32Next(hModuleSnap,&me32)); | |
355 | |
356 if (hModuleSnap != INVALID_HANDLE_VALUE) | |
357 CloseHandle(hModuleSnap); | |
358 #endif | |
359 OPENSSL_cpuid_setup(); | |
360 return 0; | |
361 } | |
362 | |
363 #else | |
364 | |
365 #ifdef __CYGWIN__ | 698 #ifdef __CYGWIN__ |
366 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ | 699 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ |
367 #include <windows.h> | 700 #include <windows.h> |
| 701 /* this has side-effect of _WIN32 getting defined, which otherwise |
| 702 * is mutually exclusive with __CYGWIN__... */ |
368 #endif | 703 #endif |
369 | 704 |
370 /* All we really need to do is remove the 'error' state when a thread | 705 /* All we really need to do is remove the 'error' state when a thread |
371 * detaches */ | 706 * detaches */ |
372 | 707 |
373 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, | 708 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, |
374 LPVOID lpvReserved) | 709 LPVOID lpvReserved) |
375 { | 710 { |
376 switch(fdwReason) | 711 switch(fdwReason) |
377 { | 712 { |
(...skipping 11 matching lines...) Expand all Loading... |
389 if (nt_headers->Signature==IMAGE_NT_SIGNATURE && | 724 if (nt_headers->Signature==IMAGE_NT_SIGNATURE && |
390 hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.Ima
geBase)) | 725 hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.Ima
geBase)) |
391 OPENSSL_NONPIC_relocated=1; | 726 OPENSSL_NONPIC_relocated=1; |
392 } | 727 } |
393 } | 728 } |
394 #endif | 729 #endif |
395 break; | 730 break; |
396 case DLL_THREAD_ATTACH: | 731 case DLL_THREAD_ATTACH: |
397 break; | 732 break; |
398 case DLL_THREAD_DETACH: | 733 case DLL_THREAD_DETACH: |
399 ERR_remove_state(0); | |
400 break; | 734 break; |
401 case DLL_PROCESS_DETACH: | 735 case DLL_PROCESS_DETACH: |
402 break; | 736 break; |
403 } | 737 } |
404 return(TRUE); | 738 return(TRUE); |
405 } | 739 } |
406 #endif | 740 #endif |
407 | 741 |
408 #endif | |
409 | |
410 #if defined(_WIN32) && !defined(__CYGWIN__) | 742 #if defined(_WIN32) && !defined(__CYGWIN__) |
411 #include <tchar.h> | 743 #include <tchar.h> |
| 744 #include <signal.h> |
| 745 #ifdef __WATCOMC__ |
| 746 #if defined(_UNICODE) || defined(__UNICODE__) |
| 747 #define _vsntprintf _vsnwprintf |
| 748 #else |
| 749 #define _vsntprintf _vsnprintf |
| 750 #endif |
| 751 #endif |
| 752 #ifdef _MSC_VER |
| 753 #define alloca _alloca |
| 754 #endif |
412 | 755 |
413 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 | 756 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 |
414 int OPENSSL_isservice(void) | 757 int OPENSSL_isservice(void) |
415 { HWINSTA h; | 758 { HWINSTA h; |
416 DWORD len; | 759 DWORD len; |
417 WCHAR *name; | 760 WCHAR *name; |
| 761 static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL }; |
| 762 |
| 763 if (_OPENSSL_isservice.p == NULL) { |
| 764 HANDLE h = GetModuleHandle(NULL); |
| 765 if (h != NULL) |
| 766 _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice"); |
| 767 if (_OPENSSL_isservice.p == NULL) |
| 768 _OPENSSL_isservice.p = (void *)-1; |
| 769 } |
| 770 |
| 771 if (_OPENSSL_isservice.p != (void *)-1) |
| 772 return (*_OPENSSL_isservice.f)(); |
418 | 773 |
419 (void)GetDesktopWindow(); /* return value is ignored */ | 774 (void)GetDesktopWindow(); /* return value is ignored */ |
420 | 775 |
421 h = GetProcessWindowStation(); | 776 h = GetProcessWindowStation(); |
422 if (h==NULL) return -1; | 777 if (h==NULL) return -1; |
423 | 778 |
424 if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) || | 779 if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) || |
425 GetLastError() != ERROR_INSUFFICIENT_BUFFER) | 780 GetLastError() != ERROR_INSUFFICIENT_BUFFER) |
426 return -1; | 781 return -1; |
427 | 782 |
428 if (len>512) return -1; /* paranoia */ | 783 if (len>512) return -1; /* paranoia */ |
429 len++,len&=~1; /* paranoia */ | 784 len++,len&=~1; /* paranoia */ |
430 #ifdef _MSC_VER | |
431 name=(WCHAR *)_alloca(len+sizeof(WCHAR)); | |
432 #else | |
433 name=(WCHAR *)alloca(len+sizeof(WCHAR)); | 785 name=(WCHAR *)alloca(len+sizeof(WCHAR)); |
434 #endif | |
435 if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len)) | 786 if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len)) |
436 return -1; | 787 return -1; |
437 | 788 |
438 len++,len&=~1; /* paranoia */ | 789 len++,len&=~1; /* paranoia */ |
439 name[len/sizeof(WCHAR)]=L'\0'; /* paranoia */ | 790 name[len/sizeof(WCHAR)]=L'\0'; /* paranoia */ |
440 #if 1 | 791 #if 1 |
441 /* This doesn't cover "interactive" services [working with real | 792 /* This doesn't cover "interactive" services [working with real |
442 * WinSta0's] nor programs started non-interactively by Task | 793 * WinSta0's] nor programs started non-interactively by Task |
443 * Scheduler [those are working with SAWinSta]. */ | 794 * Scheduler [those are working with SAWinSta]. */ |
444 if (wcsstr(name,L"Service-0x")) return 1; | 795 if (wcsstr(name,L"Service-0x")) return 1; |
(...skipping 24 matching lines...) Expand all Loading... |
469 } | 820 } |
470 #endif | 821 #endif |
471 | 822 |
472 if (sizeof(TCHAR)==sizeof(char)) | 823 if (sizeof(TCHAR)==sizeof(char)) |
473 fmt=(const TCHAR *)fmta; | 824 fmt=(const TCHAR *)fmta; |
474 else do | 825 else do |
475 { int keepgoing; | 826 { int keepgoing; |
476 size_t len_0=strlen(fmta)+1,i; | 827 size_t len_0=strlen(fmta)+1,i; |
477 WCHAR *fmtw; | 828 WCHAR *fmtw; |
478 | 829 |
479 #ifdef _MSC_VER | 830 » fmtw = (WCHAR *)alloca(len_0*sizeof(WCHAR)); |
480 » fmtw = (WCHAR *)_alloca (len_0*sizeof(WCHAR)); | |
481 #else | |
482 » fmtw = (WCHAR *)alloca (len_0*sizeof(WCHAR)); | |
483 #endif | |
484 if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; } | 831 if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; } |
485 | 832 |
486 #ifndef OPENSSL_NO_MULTIBYTE | 833 #ifndef OPENSSL_NO_MULTIBYTE |
487 if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0)) | 834 if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0)) |
488 #endif | 835 #endif |
489 for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i]; | 836 for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i]; |
490 | 837 |
491 for (i=0;i<len_0;i++) | 838 for (i=0;i<len_0;i++) |
492 { if (fmtw[i]==L'%') do | 839 { if (fmtw[i]==L'%') do |
493 { keepgoing=0; | 840 { keepgoing=0; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 va_end (ap); | 879 va_end (ap); |
533 } | 880 } |
534 int OPENSSL_isservice (void) { return 0; } | 881 int OPENSSL_isservice (void) { return 0; } |
535 #endif | 882 #endif |
536 | 883 |
537 void OpenSSLDie(const char *file,int line,const char *assertion) | 884 void OpenSSLDie(const char *file,int line,const char *assertion) |
538 { | 885 { |
539 OPENSSL_showfatal( | 886 OPENSSL_showfatal( |
540 "%s(%d): OpenSSL internal error, assertion failed: %s\n", | 887 "%s(%d): OpenSSL internal error, assertion failed: %s\n", |
541 file,line,assertion); | 888 file,line,assertion); |
| 889 #if !defined(_WIN32) || defined(__CYGWIN__) |
542 abort(); | 890 abort(); |
| 891 #else |
| 892 /* Win32 abort() customarily shows a dialog, but we just did that... */ |
| 893 raise(SIGABRT); |
| 894 _exit(3); |
| 895 #endif |
543 } | 896 } |
544 | 897 |
545 void *OPENSSL_stderr(void) { return stderr; } | 898 void *OPENSSL_stderr(void) { return stderr; } |
OLD | NEW |