1/* crypto/threads/mttest.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59#include <stdio.h> 60#include <stdlib.h> 61#include <string.h> 62#include <errno.h> 63#ifdef LINUX 64#include <typedefs.h> 65#endif 66#ifdef OPENSSL_SYS_WIN32 67#include <windows.h> 68#endif 69#ifdef SOLARIS 70#include <synch.h> 71#include <thread.h> 72#endif 73#ifdef IRIX 74#include <ulocks.h> 75#include <sys/prctl.h> 76#endif 77#ifdef PTHREADS 78#include <pthread.h> 79#endif 80#ifdef OPENSSL_SYS_NETWARE 81#if !defined __int64 82# define __int64 long long 83#endif 84#include <nwmpk.h> 85#endif 86#include <openssl/lhash.h> 87#include <openssl/crypto.h> 88#include <openssl/buffer.h> 89#include "e_os.h" 90#include <openssl/x509.h> 91#include <openssl/ssl.h> 92#include <openssl/err.h> 93#include <openssl/rand.h> 94 95#ifdef OPENSSL_NO_FP_API 96#define APPS_WIN16 97#include "../buffer/bss_file.c" 98#endif 99 100#ifdef OPENSSL_SYS_NETWARE 101#define TEST_SERVER_CERT "/openssl/apps/server.pem" 102#define TEST_CLIENT_CERT "/openssl/apps/client.pem" 103#else 104#define TEST_SERVER_CERT "../../apps/server.pem" 105#define TEST_CLIENT_CERT "../../apps/client.pem" 106#endif 107 108#define MAX_THREAD_NUMBER 100 109 110int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs); 111void thread_setup(void); 112void thread_cleanup(void); 113void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx); 114 115void irix_locking_callback(int mode,int type,char *file,int line); 116void solaris_locking_callback(int mode,int type,char *file,int line); 117void win32_locking_callback(int mode,int type,char *file,int line); 118void pthreads_locking_callback(int mode,int type,char *file,int line); 119void netware_locking_callback(int mode,int type,char *file,int line); 120void beos_locking_callback(int mode,int type,const char *file,int line); 121 122unsigned long irix_thread_id(void ); 123unsigned long solaris_thread_id(void ); 124unsigned long pthreads_thread_id(void ); 125unsigned long netware_thread_id(void ); 126unsigned long beos_thread_id(void ); 127 128#if defined(OPENSSL_SYS_NETWARE) 129static MPKMutex *lock_cs; 130static MPKSema ThreadSem; 131static long *lock_count; 132#endif 133 134BIO *bio_err=NULL; 135BIO *bio_stdout=NULL; 136 137static char *cipher=NULL; 138int verbose=0; 139#ifdef FIONBIO 140static int s_nbio=0; 141#endif 142 143int thread_number=10; 144int number_of_loops=10; 145int reconnect=0; 146int cache_stats=0; 147 148static const char rnd_seed[] = "string to make the random number generator think it has entropy"; 149 150int doit(char *ctx[4]); 151static void print_stats(FILE *fp, SSL_CTX *ctx) 152{ 153 fprintf(fp,"%4ld items in the session cache\n", 154 SSL_CTX_sess_number(ctx)); 155 fprintf(fp,"%4ld client connects (SSL_connect())\n", 156 SSL_CTX_sess_connect(ctx)); 157 fprintf(fp,"%4ld client connects that finished\n", 158 SSL_CTX_sess_connect_good(ctx)); 159 fprintf(fp,"%4ld server connects (SSL_accept())\n", 160 SSL_CTX_sess_accept(ctx)); 161 fprintf(fp,"%4ld server connects that finished\n", 162 SSL_CTX_sess_accept_good(ctx)); 163 fprintf(fp,"%4ld session cache hits\n",SSL_CTX_sess_hits(ctx)); 164 fprintf(fp,"%4ld session cache misses\n",SSL_CTX_sess_misses(ctx)); 165 fprintf(fp,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ctx)); 166 } 167 168static void sv_usage(void) 169 { 170 fprintf(stderr,"usage: ssltest [args ...]\n"); 171 fprintf(stderr,"\n"); 172 fprintf(stderr," -server_auth - check server certificate\n"); 173 fprintf(stderr," -client_auth - do client authentication\n"); 174 fprintf(stderr," -v - more output\n"); 175 fprintf(stderr," -CApath arg - PEM format directory of CA's\n"); 176 fprintf(stderr," -CAfile arg - PEM format file of CA's\n"); 177 fprintf(stderr," -threads arg - number of threads\n"); 178 fprintf(stderr," -loops arg - number of 'connections', per thread\n"); 179 fprintf(stderr," -reconnect - reuse session-id's\n"); 180 fprintf(stderr," -stats - server session-id cache stats\n"); 181 fprintf(stderr," -cert arg - server certificate/key\n"); 182 fprintf(stderr," -ccert arg - client certificate/key\n"); 183 fprintf(stderr," -ssl3 - just SSLv3n\n"); 184 } 185 186int main(int argc, char *argv[]) 187 { 188 char *CApath=NULL,*CAfile=NULL; 189 int badop=0; 190 int ret=1; 191 int client_auth=0; 192 int server_auth=0; 193 SSL_CTX *s_ctx=NULL; 194 SSL_CTX *c_ctx=NULL; 195 const char *scert=TEST_SERVER_CERT; 196 const char *ccert=TEST_CLIENT_CERT; 197 const SSL_METHOD *ssl_method=SSLv23_method(); 198 199 RAND_seed(rnd_seed, sizeof rnd_seed); 200 201 if (bio_err == NULL) 202 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 203 if (bio_stdout == NULL) 204 bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE); 205 argc--; 206 argv++; 207 208 while (argc >= 1) 209 { 210 if (strcmp(*argv,"-server_auth") == 0) 211 server_auth=1; 212 else if (strcmp(*argv,"-client_auth") == 0) 213 client_auth=1; 214 else if (strcmp(*argv,"-reconnect") == 0) 215 reconnect=1; 216 else if (strcmp(*argv,"-stats") == 0) 217 cache_stats=1; 218 else if (strcmp(*argv,"-ssl3") == 0) 219 ssl_method=SSLv3_method(); 220 else if (strcmp(*argv,"-ssl2") == 0) 221 ssl_method=SSLv2_method(); 222 else if (strcmp(*argv,"-CApath") == 0) 223 { 224 if (--argc < 1) goto bad; 225 CApath= *(++argv); 226 } 227 else if (strcmp(*argv,"-CAfile") == 0) 228 { 229 if (--argc < 1) goto bad; 230 CAfile= *(++argv); 231 } 232 else if (strcmp(*argv,"-cert") == 0) 233 { 234 if (--argc < 1) goto bad; 235 scert= *(++argv); 236 } 237 else if (strcmp(*argv,"-ccert") == 0) 238 { 239 if (--argc < 1) goto bad; 240 ccert= *(++argv); 241 } 242 else if (strcmp(*argv,"-threads") == 0) 243 { 244 if (--argc < 1) goto bad; 245 thread_number= atoi(*(++argv)); 246 if (thread_number == 0) thread_number=1; 247 if (thread_number > MAX_THREAD_NUMBER) 248 thread_number=MAX_THREAD_NUMBER; 249 } 250 else if (strcmp(*argv,"-loops") == 0) 251 { 252 if (--argc < 1) goto bad; 253 number_of_loops= atoi(*(++argv)); 254 if (number_of_loops == 0) number_of_loops=1; 255 } 256 else 257 { 258 fprintf(stderr,"unknown option %s\n",*argv); 259 badop=1; 260 break; 261 } 262 argc--; 263 argv++; 264 } 265 if (badop) 266 { 267bad: 268 sv_usage(); 269 goto end; 270 } 271 272 if (cipher == NULL && OPENSSL_issetugid() == 0) 273 cipher=getenv("SSL_CIPHER"); 274 275 SSL_load_error_strings(); 276 OpenSSL_add_ssl_algorithms(); 277 278 c_ctx=SSL_CTX_new(ssl_method); 279 s_ctx=SSL_CTX_new(ssl_method); 280 if ((c_ctx == NULL) || (s_ctx == NULL)) 281 { 282 ERR_print_errors(bio_err); 283 goto end; 284 } 285 286 SSL_CTX_set_session_cache_mode(s_ctx, 287 SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER); 288 SSL_CTX_set_session_cache_mode(c_ctx, 289 SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER); 290 291 if (!SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM)) 292 { 293 ERR_print_errors(bio_err); 294 } 295 else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM)) 296 { 297 ERR_print_errors(bio_err); 298 goto end; 299 } 300 301 if (client_auth) 302 { 303 SSL_CTX_use_certificate_file(c_ctx,ccert, 304 SSL_FILETYPE_PEM); 305 SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert, 306 SSL_FILETYPE_PEM); 307 } 308 309 if ( (!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) || 310 (!SSL_CTX_set_default_verify_paths(s_ctx)) || 311 (!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) || 312 (!SSL_CTX_set_default_verify_paths(c_ctx))) 313 { 314 fprintf(stderr,"SSL_load_verify_locations\n"); 315 ERR_print_errors(bio_err); 316 goto end; 317 } 318 319 if (client_auth) 320 { 321 fprintf(stderr,"client authentication\n"); 322 SSL_CTX_set_verify(s_ctx, 323 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 324 verify_callback); 325 } 326 if (server_auth) 327 { 328 fprintf(stderr,"server authentication\n"); 329 SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER, 330 verify_callback); 331 } 332 333 thread_setup(); 334 do_threads(s_ctx,c_ctx); 335 thread_cleanup(); 336end: 337 338 if (c_ctx != NULL) 339 { 340 fprintf(stderr,"Client SSL_CTX stats then free it\n"); 341 print_stats(stderr,c_ctx); 342 SSL_CTX_free(c_ctx); 343 } 344 if (s_ctx != NULL) 345 { 346 fprintf(stderr,"Server SSL_CTX stats then free it\n"); 347 print_stats(stderr,s_ctx); 348 if (cache_stats) 349 { 350 fprintf(stderr,"-----\n"); 351 lh_stats((_LHASH *)SSL_CTX_sessions(s_ctx),stderr); 352 fprintf(stderr,"-----\n"); 353 /* lh_node_stats((_LHASH *)SSL_CTX_sessions(s_ctx),stderr); 354 fprintf(stderr,"-----\n"); */ 355 lh_node_usage_stats((_LHASH *)SSL_CTX_sessions(s_ctx),stderr); 356 fprintf(stderr,"-----\n"); 357 } 358 SSL_CTX_free(s_ctx); 359 fprintf(stderr,"done free\n"); 360 } 361 exit(ret); 362 return(0); 363 } 364 365#define W_READ 1 366#define W_WRITE 2 367#define C_DONE 1 368#define S_DONE 2 369 370static int ndoit(SSL_CTX *ssl_ctx[2]) 371 { 372 int i; 373 int ret; 374 char *ctx[4]; 375 376 ctx[0]=(char *)ssl_ctx[0]; 377 ctx[1]=(char *)ssl_ctx[1]; 378 379 if (reconnect) 380 { 381 ctx[2]=(char *)SSL_new(ssl_ctx[0]); 382 ctx[3]=(char *)SSL_new(ssl_ctx[1]); 383 } 384 else 385 { 386 ctx[2]=NULL; 387 ctx[3]=NULL; 388 } 389 390 fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id()); 391 for (i=0; i<number_of_loops; i++) 392 { 393/* fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n", 394 CRYPTO_thread_id(),i, 395 ssl_ctx[0]->references, 396 ssl_ctx[1]->references); */ 397 /* pthread_delay_np(&tm);*/ 398 399 ret=doit(ctx); 400 if (ret != 0) 401 { 402 fprintf(stdout,"error[%d] %lu - %d\n", 403 i,CRYPTO_thread_id(),ret); 404 return(ret); 405 } 406 } 407 fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id()); 408 if (reconnect) 409 { 410 SSL_free((SSL *)ctx[2]); 411 SSL_free((SSL *)ctx[3]); 412 } 413# ifdef OPENSSL_SYS_NETWARE 414 MPKSemaphoreSignal(ThreadSem); 415# endif 416 return(0); 417 } 418 419int doit(char *ctx[4]) 420 { 421 SSL_CTX *s_ctx,*c_ctx; 422 static char cbuf[200],sbuf[200]; 423 SSL *c_ssl=NULL; 424 SSL *s_ssl=NULL; 425 BIO *c_to_s=NULL; 426 BIO *s_to_c=NULL; 427 BIO *c_bio=NULL; 428 BIO *s_bio=NULL; 429 int c_r,c_w,s_r,s_w; 430 int i; 431 int done=0; 432 int c_write,s_write; 433 int do_server=0,do_client=0; 434 435 s_ctx=(SSL_CTX *)ctx[0]; 436 c_ctx=(SSL_CTX *)ctx[1]; 437 438 if (ctx[2] != NULL) 439 s_ssl=(SSL *)ctx[2]; 440 else 441 s_ssl=SSL_new(s_ctx); 442 443 if (ctx[3] != NULL) 444 c_ssl=(SSL *)ctx[3]; 445 else 446 c_ssl=SSL_new(c_ctx); 447 448 if ((s_ssl == NULL) || (c_ssl == NULL)) goto err; 449 450 c_to_s=BIO_new(BIO_s_mem()); 451 s_to_c=BIO_new(BIO_s_mem()); 452 if ((s_to_c == NULL) || (c_to_s == NULL)) goto err; 453 454 c_bio=BIO_new(BIO_f_ssl()); 455 s_bio=BIO_new(BIO_f_ssl()); 456 if ((c_bio == NULL) || (s_bio == NULL)) goto err; 457 458 SSL_set_connect_state(c_ssl); 459 SSL_set_bio(c_ssl,s_to_c,c_to_s); 460 BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE); 461 462 SSL_set_accept_state(s_ssl); 463 SSL_set_bio(s_ssl,c_to_s,s_to_c); 464 BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE); 465 466 c_r=0; s_r=1; 467 c_w=1; s_w=0; 468 c_write=1,s_write=0; 469 470 /* We can always do writes */ 471 for (;;) 472 { 473 do_server=0; 474 do_client=0; 475 476 i=(int)BIO_pending(s_bio); 477 if ((i && s_r) || s_w) do_server=1; 478 479 i=(int)BIO_pending(c_bio); 480 if ((i && c_r) || c_w) do_client=1; 481 482 if (do_server && verbose) 483 { 484 if (SSL_in_init(s_ssl)) 485 printf("server waiting in SSL_accept - %s\n", 486 SSL_state_string_long(s_ssl)); 487 else if (s_write) 488 printf("server:SSL_write()\n"); 489 else 490 printf("server:SSL_read()\n"); 491 } 492 493 if (do_client && verbose) 494 { 495 if (SSL_in_init(c_ssl)) 496 printf("client waiting in SSL_connect - %s\n", 497 SSL_state_string_long(c_ssl)); 498 else if (c_write) 499 printf("client:SSL_write()\n"); 500 else 501 printf("client:SSL_read()\n"); 502 } 503 504 if (!do_client && !do_server) 505 { 506 fprintf(stdout,"ERROR IN STARTUP\n"); 507 break; 508 } 509 if (do_client && !(done & C_DONE)) 510 { 511 if (c_write) 512 { 513 i=BIO_write(c_bio,"hello from client\n",18); 514 if (i < 0) 515 { 516 c_r=0; 517 c_w=0; 518 if (BIO_should_retry(c_bio)) 519 { 520 if (BIO_should_read(c_bio)) 521 c_r=1; 522 if (BIO_should_write(c_bio)) 523 c_w=1; 524 } 525 else 526 { 527 fprintf(stderr,"ERROR in CLIENT\n"); 528 ERR_print_errors_fp(stderr); 529 return(1); 530 } 531 } 532 else if (i == 0) 533 { 534 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 535 return(1); 536 } 537 else 538 { 539 /* ok */ 540 c_write=0; 541 } 542 } 543 else 544 { 545 i=BIO_read(c_bio,cbuf,100); 546 if (i < 0) 547 { 548 c_r=0; 549 c_w=0; 550 if (BIO_should_retry(c_bio)) 551 { 552 if (BIO_should_read(c_bio)) 553 c_r=1; 554 if (BIO_should_write(c_bio)) 555 c_w=1; 556 } 557 else 558 { 559 fprintf(stderr,"ERROR in CLIENT\n"); 560 ERR_print_errors_fp(stderr); 561 return(1); 562 } 563 } 564 else if (i == 0) 565 { 566 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 567 return(1); 568 } 569 else 570 { 571 done|=C_DONE; 572#ifdef undef 573 fprintf(stdout,"CLIENT:from server:"); 574 fwrite(cbuf,1,i,stdout); 575 fflush(stdout); 576#endif 577 } 578 } 579 } 580 581 if (do_server && !(done & S_DONE)) 582 { 583 if (!s_write) 584 { 585 i=BIO_read(s_bio,sbuf,100); 586 if (i < 0) 587 { 588 s_r=0; 589 s_w=0; 590 if (BIO_should_retry(s_bio)) 591 { 592 if (BIO_should_read(s_bio)) 593 s_r=1; 594 if (BIO_should_write(s_bio)) 595 s_w=1; 596 } 597 else 598 { 599 fprintf(stderr,"ERROR in SERVER\n"); 600 ERR_print_errors_fp(stderr); 601 return(1); 602 } 603 } 604 else if (i == 0) 605 { 606 fprintf(stderr,"SSL SERVER STARTUP FAILED\n"); 607 return(1); 608 } 609 else 610 { 611 s_write=1; 612 s_w=1; 613#ifdef undef 614 fprintf(stdout,"SERVER:from client:"); 615 fwrite(sbuf,1,i,stdout); 616 fflush(stdout); 617#endif 618 } 619 } 620 else 621 { 622 i=BIO_write(s_bio,"hello from server\n",18); 623 if (i < 0) 624 { 625 s_r=0; 626 s_w=0; 627 if (BIO_should_retry(s_bio)) 628 { 629 if (BIO_should_read(s_bio)) 630 s_r=1; 631 if (BIO_should_write(s_bio)) 632 s_w=1; 633 } 634 else 635 { 636 fprintf(stderr,"ERROR in SERVER\n"); 637 ERR_print_errors_fp(stderr); 638 return(1); 639 } 640 } 641 else if (i == 0) 642 { 643 fprintf(stderr,"SSL SERVER STARTUP FAILED\n"); 644 return(1); 645 } 646 else 647 { 648 s_write=0; 649 s_r=1; 650 done|=S_DONE; 651 } 652 } 653 } 654 655 if ((done & S_DONE) && (done & C_DONE)) break; 656# if defined(OPENSSL_SYS_NETWARE) 657 ThreadSwitchWithDelay(); 658# endif 659 } 660 661 SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 662 SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 663 664#ifdef undef 665 fprintf(stdout,"DONE\n"); 666#endif 667err: 668 /* We have to set the BIO's to NULL otherwise they will be 669 * free()ed twice. Once when th s_ssl is SSL_free()ed and 670 * again when c_ssl is SSL_free()ed. 671 * This is a hack required because s_ssl and c_ssl are sharing the same 672 * BIO structure and SSL_set_bio() and SSL_free() automatically 673 * BIO_free non NULL entries. 674 * You should not normally do this or be required to do this */ 675 676 if (s_ssl != NULL) 677 { 678 s_ssl->rbio=NULL; 679 s_ssl->wbio=NULL; 680 } 681 if (c_ssl != NULL) 682 { 683 c_ssl->rbio=NULL; 684 c_ssl->wbio=NULL; 685 } 686 687 /* The SSL's are optionally freed in the following calls */ 688 if (c_to_s != NULL) BIO_free(c_to_s); 689 if (s_to_c != NULL) BIO_free(s_to_c); 690 691 if (c_bio != NULL) BIO_free(c_bio); 692 if (s_bio != NULL) BIO_free(s_bio); 693 return(0); 694 } 695 696int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 697 { 698 char *s, buf[256]; 699 700 if (verbose) 701 { 702 s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), 703 buf,256); 704 if (s != NULL) 705 { 706 if (ok) 707 fprintf(stderr,"depth=%d %s\n", 708 ctx->error_depth,buf); 709 else 710 fprintf(stderr,"depth=%d error=%d %s\n", 711 ctx->error_depth,ctx->error,buf); 712 } 713 } 714 return(ok); 715 } 716 717#define THREAD_STACK_SIZE (16*1024) 718 719#ifdef OPENSSL_SYS_WIN32 720 721static HANDLE *lock_cs; 722 723void thread_setup(void) 724 { 725 int i; 726 727 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); 728 for (i=0; i<CRYPTO_num_locks(); i++) 729 { 730 lock_cs[i]=CreateMutex(NULL,FALSE,NULL); 731 } 732 733 CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback); 734 /* id callback defined */ 735 } 736 737void thread_cleanup(void) 738 { 739 int i; 740 741 CRYPTO_set_locking_callback(NULL); 742 for (i=0; i<CRYPTO_num_locks(); i++) 743 CloseHandle(lock_cs[i]); 744 OPENSSL_free(lock_cs); 745 } 746 747void win32_locking_callback(int mode, int type, char *file, int line) 748 { 749 if (mode & CRYPTO_LOCK) 750 { 751 WaitForSingleObject(lock_cs[type],INFINITE); 752 } 753 else 754 { 755 ReleaseMutex(lock_cs[type]); 756 } 757 } 758 759void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 760 { 761 double ret; 762 SSL_CTX *ssl_ctx[2]; 763 DWORD thread_id[MAX_THREAD_NUMBER]; 764 HANDLE thread_handle[MAX_THREAD_NUMBER]; 765 int i; 766 SYSTEMTIME start,end; 767 768 ssl_ctx[0]=s_ctx; 769 ssl_ctx[1]=c_ctx; 770 771 GetSystemTime(&start); 772 for (i=0; i<thread_number; i++) 773 { 774 thread_handle[i]=CreateThread(NULL, 775 THREAD_STACK_SIZE, 776 (LPTHREAD_START_ROUTINE)ndoit, 777 (void *)ssl_ctx, 778 0L, 779 &(thread_id[i])); 780 } 781 782 printf("reaping\n"); 783 for (i=0; i<thread_number; i+=50) 784 { 785 int j; 786 787 j=(thread_number < (i+50))?(thread_number-i):50; 788 789 if (WaitForMultipleObjects(j, 790 (CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE) 791 == WAIT_FAILED) 792 { 793 fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError()); 794 exit(1); 795 } 796 } 797 GetSystemTime(&end); 798 799 if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7; 800 ret=(end.wDayOfWeek-start.wDayOfWeek)*24; 801 802 ret=(ret+end.wHour-start.wHour)*60; 803 ret=(ret+end.wMinute-start.wMinute)*60; 804 ret=(ret+end.wSecond-start.wSecond); 805 ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0; 806 807 printf("win32 threads done - %.3f seconds\n",ret); 808 } 809 810#endif /* OPENSSL_SYS_WIN32 */ 811 812#ifdef SOLARIS 813 814static mutex_t *lock_cs; 815/*static rwlock_t *lock_cs; */ 816static long *lock_count; 817 818void thread_setup(void) 819 { 820 int i; 821 822 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); 823 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 824 for (i=0; i<CRYPTO_num_locks(); i++) 825 { 826 lock_count[i]=0; 827 /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */ 828 mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL); 829 } 830 831 CRYPTO_set_id_callback((unsigned long (*)(void))solaris_thread_id); 832 CRYPTO_set_locking_callback((void (*)(void))solaris_locking_callback); 833 } 834 835void thread_cleanup(void) 836 { 837 int i; 838 839 CRYPTO_set_locking_callback(NULL); 840 841 fprintf(stderr,"cleanup\n"); 842 843 for (i=0; i<CRYPTO_num_locks(); i++) 844 { 845 /* rwlock_destroy(&(lock_cs[i])); */ 846 mutex_destroy(&(lock_cs[i])); 847 fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i)); 848 } 849 OPENSSL_free(lock_cs); 850 OPENSSL_free(lock_count); 851 852 fprintf(stderr,"done cleanup\n"); 853 854 } 855 856void solaris_locking_callback(int mode, int type, char *file, int line) 857 { 858#ifdef undef 859 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", 860 CRYPTO_thread_id(), 861 (mode&CRYPTO_LOCK)?"l":"u", 862 (type&CRYPTO_READ)?"r":"w",file,line); 863#endif 864 865 /* 866 if (CRYPTO_LOCK_SSL_CERT == type) 867 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", 868 CRYPTO_thread_id(), 869 mode,file,line); 870 */ 871 if (mode & CRYPTO_LOCK) 872 { 873 /* if (mode & CRYPTO_READ) 874 rw_rdlock(&(lock_cs[type])); 875 else 876 rw_wrlock(&(lock_cs[type])); */ 877 878 mutex_lock(&(lock_cs[type])); 879 lock_count[type]++; 880 } 881 else 882 { 883/* rw_unlock(&(lock_cs[type])); */ 884 mutex_unlock(&(lock_cs[type])); 885 } 886 } 887 888void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 889 { 890 SSL_CTX *ssl_ctx[2]; 891 thread_t thread_ctx[MAX_THREAD_NUMBER]; 892 int i; 893 894 ssl_ctx[0]=s_ctx; 895 ssl_ctx[1]=c_ctx; 896 897 thr_setconcurrency(thread_number); 898 for (i=0; i<thread_number; i++) 899 { 900 thr_create(NULL, THREAD_STACK_SIZE, 901 (void *(*)())ndoit, 902 (void *)ssl_ctx, 903 0L, 904 &(thread_ctx[i])); 905 } 906 907 printf("reaping\n"); 908 for (i=0; i<thread_number; i++) 909 { 910 thr_join(thread_ctx[i],NULL,NULL); 911 } 912 913 printf("solaris threads done (%d,%d)\n", 914 s_ctx->references,c_ctx->references); 915 } 916 917unsigned long solaris_thread_id(void) 918 { 919 unsigned long ret; 920 921 ret=(unsigned long)thr_self(); 922 return(ret); 923 } 924#endif /* SOLARIS */ 925 926#ifdef IRIX 927 928 929static usptr_t *arena; 930static usema_t **lock_cs; 931 932void thread_setup(void) 933 { 934 int i; 935 char filename[20]; 936 937 strlcpy(filename,"/tmp/mttest.XXXXXX", sizeof(filename)); 938 mktemp(filename); 939 940 usconfig(CONF_STHREADIOOFF); 941 usconfig(CONF_STHREADMALLOCOFF); 942 usconfig(CONF_INITUSERS,100); 943 usconfig(CONF_LOCKTYPE,US_DEBUGPLUS); 944 arena=usinit(filename); 945 unlink(filename); 946 947 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); 948 for (i=0; i<CRYPTO_num_locks(); i++) 949 { 950 lock_cs[i]=usnewsema(arena,1); 951 } 952 953 CRYPTO_set_id_callback((unsigned long (*)(void))irix_thread_id); 954 CRYPTO_set_locking_callback((void (*)(void))irix_locking_callback); 955 } 956 957void thread_cleanup(void) 958 { 959 int i; 960 961 CRYPTO_set_locking_callback(NULL); 962 for (i=0; i<CRYPTO_num_locks(); i++) 963 { 964 char buf[10]; 965 966 snprintf(buf, sizeof(buf), "%2d:",i); 967 usdumpsema(lock_cs[i],stdout,buf); 968 usfreesema(lock_cs[i],arena); 969 } 970 OPENSSL_free(lock_cs); 971 } 972 973void irix_locking_callback(int mode, int type, char *file, int line) 974 { 975 if (mode & CRYPTO_LOCK) 976 { 977 printf("lock %d\n",type); 978 uspsema(lock_cs[type]); 979 } 980 else 981 { 982 printf("unlock %d\n",type); 983 usvsema(lock_cs[type]); 984 } 985 } 986 987void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 988 { 989 SSL_CTX *ssl_ctx[2]; 990 int thread_ctx[MAX_THREAD_NUMBER]; 991 int i; 992 993 ssl_ctx[0]=s_ctx; 994 ssl_ctx[1]=c_ctx; 995 996 for (i=0; i<thread_number; i++) 997 { 998 thread_ctx[i]=sproc((void (*)())ndoit, 999 PR_SADDR|PR_SFDS,(void *)ssl_ctx); 1000 } 1001 1002 printf("reaping\n"); 1003 for (i=0; i<thread_number; i++) 1004 { 1005 wait(NULL); 1006 } 1007 1008 printf("irix threads done (%d,%d)\n", 1009 s_ctx->references,c_ctx->references); 1010 } 1011 1012unsigned long irix_thread_id(void) 1013 { 1014 unsigned long ret; 1015 1016 ret=(unsigned long)getpid(); 1017 return(ret); 1018 } 1019#endif /* IRIX */ 1020 1021#ifdef PTHREADS 1022 1023static pthread_mutex_t *lock_cs; 1024static long *lock_count; 1025 1026void thread_setup(void) 1027 { 1028 int i; 1029 1030 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); 1031 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1032 for (i=0; i<CRYPTO_num_locks(); i++) 1033 { 1034 lock_count[i]=0; 1035 pthread_mutex_init(&(lock_cs[i]),NULL); 1036 } 1037 1038 CRYPTO_set_id_callback((unsigned long (*)(void))pthreads_thread_id); 1039 CRYPTO_set_locking_callback((void (*)(int, int, const char *, int))pthreads_locking_callback); 1040 } 1041 1042void thread_cleanup(void) 1043 { 1044 int i; 1045 1046 CRYPTO_set_locking_callback(NULL); 1047 fprintf(stderr,"cleanup\n"); 1048 for (i=0; i<CRYPTO_num_locks(); i++) 1049 { 1050 pthread_mutex_destroy(&(lock_cs[i])); 1051 fprintf(stderr,"%8ld:%s\n",lock_count[i], 1052 CRYPTO_get_lock_name(i)); 1053 } 1054 OPENSSL_free(lock_cs); 1055 OPENSSL_free(lock_count); 1056 1057 fprintf(stderr,"done cleanup\n"); 1058 } 1059 1060void pthreads_locking_callback(int mode, int type, char *file, 1061 int line) 1062 { 1063#ifdef undef 1064 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", 1065 CRYPTO_thread_id(), 1066 (mode&CRYPTO_LOCK)?"l":"u", 1067 (type&CRYPTO_READ)?"r":"w",file,line); 1068#endif 1069/* 1070 if (CRYPTO_LOCK_SSL_CERT == type) 1071 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", 1072 CRYPTO_thread_id(), 1073 mode,file,line); 1074*/ 1075 if (mode & CRYPTO_LOCK) 1076 { 1077 pthread_mutex_lock(&(lock_cs[type])); 1078 lock_count[type]++; 1079 } 1080 else 1081 { 1082 pthread_mutex_unlock(&(lock_cs[type])); 1083 } 1084 } 1085 1086void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1087 { 1088 SSL_CTX *ssl_ctx[2]; 1089 pthread_t thread_ctx[MAX_THREAD_NUMBER]; 1090 int i; 1091 1092 ssl_ctx[0]=s_ctx; 1093 ssl_ctx[1]=c_ctx; 1094 1095 /* 1096 thr_setconcurrency(thread_number); 1097 */ 1098 for (i=0; i<thread_number; i++) 1099 { 1100 pthread_create(&(thread_ctx[i]), NULL, 1101 (void *(*)(void *))ndoit, (void *)ssl_ctx); 1102 } 1103 1104 printf("reaping\n"); 1105 for (i=0; i<thread_number; i++) 1106 { 1107 pthread_join(thread_ctx[i],NULL); 1108 } 1109 1110 printf("pthreads threads done (%d,%d)\n", 1111 s_ctx->references,c_ctx->references); 1112 } 1113 1114unsigned long pthreads_thread_id(void) 1115 { 1116 unsigned long ret; 1117 1118 ret=(unsigned long)pthread_self(); 1119 return(ret); 1120 } 1121 1122#endif /* PTHREADS */ 1123 1124 1125 1126#ifdef OPENSSL_SYS_NETWARE 1127 1128void thread_setup(void) 1129{ 1130 int i; 1131 1132 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex)); 1133 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1134 for (i=0; i<CRYPTO_num_locks(); i++) 1135 { 1136 lock_count[i]=0; 1137 lock_cs[i]=MPKMutexAlloc("OpenSSL mutex"); 1138 } 1139 1140 ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 ); 1141 1142 CRYPTO_set_id_callback((unsigned long (*)(void))netware_thread_id); 1143 CRYPTO_set_locking_callback((void (*)(void))netware_locking_callback); 1144} 1145 1146void thread_cleanup(void) 1147{ 1148 int i; 1149 1150 CRYPTO_set_locking_callback(NULL); 1151 1152 fprintf(stdout,"thread_cleanup\n"); 1153 1154 for (i=0; i<CRYPTO_num_locks(); i++) 1155 { 1156 MPKMutexFree(lock_cs[i]); 1157 fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i)); 1158 } 1159 OPENSSL_free(lock_cs); 1160 OPENSSL_free(lock_count); 1161 1162 MPKSemaphoreFree(ThreadSem); 1163 1164 fprintf(stdout,"done cleanup\n"); 1165} 1166 1167void netware_locking_callback(int mode, int type, char *file, int line) 1168{ 1169 if (mode & CRYPTO_LOCK) 1170 { 1171 MPKMutexLock(lock_cs[type]); 1172 lock_count[type]++; 1173 } 1174 else 1175 MPKMutexUnlock(lock_cs[type]); 1176} 1177 1178void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1179{ 1180 SSL_CTX *ssl_ctx[2]; 1181 int i; 1182 ssl_ctx[0]=s_ctx; 1183 ssl_ctx[1]=c_ctx; 1184 1185 for (i=0; i<thread_number; i++) 1186 { 1187 BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE, 1188 (void*)ssl_ctx); 1189 ThreadSwitchWithDelay(); 1190 } 1191 1192 printf("reaping\n"); 1193 1194 /* loop until all threads have signaled the semaphore */ 1195 for (i=0; i<thread_number; i++) 1196 { 1197 MPKSemaphoreWait(ThreadSem); 1198 } 1199 printf("netware threads done (%d,%d)\n", 1200 s_ctx->references,c_ctx->references); 1201} 1202 1203unsigned long netware_thread_id(void) 1204{ 1205 unsigned long ret; 1206 1207 ret=(unsigned long)GetThreadID(); 1208 return(ret); 1209} 1210#endif /* NETWARE */ 1211 1212#ifdef BEOS_THREADS 1213 1214#include <Locker.h> 1215 1216static BLocker** lock_cs; 1217static long* lock_count; 1218 1219void thread_setup(void) 1220 { 1221 int i; 1222 1223 lock_cs=(BLocker**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(BLocker*)); 1224 lock_count=(long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1225 for (i=0; i<CRYPTO_num_locks(); i++) 1226 { 1227 lock_count[i]=0; 1228 lock_cs[i] = new BLocker(CRYPTO_get_lock_name(i)); 1229 } 1230 1231 CRYPTO_set_id_callback((unsigned long (*)(void))beos_thread_id); 1232 CRYPTO_set_locking_callback(beos_locking_callback); 1233 } 1234 1235void thread_cleanup(void) 1236 { 1237 int i; 1238 1239 CRYPTO_set_locking_callback(NULL); 1240 fprintf(stderr,"cleanup\n"); 1241 for (i=0; i<CRYPTO_num_locks(); i++) 1242 { 1243 delete lock_cs[i]; 1244 fprintf(stderr,"%8ld:%s\n",lock_count[i], 1245 CRYPTO_get_lock_name(i)); 1246 } 1247 OPENSSL_free(lock_cs); 1248 OPENSSL_free(lock_count); 1249 1250 fprintf(stderr,"done cleanup\n"); 1251 } 1252 1253void beos_locking_callback(int mode, int type, const char *file, int line) 1254 { 1255#if 0 1256 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", 1257 CRYPTO_thread_id(), 1258 (mode&CRYPTO_LOCK)?"l":"u", 1259 (type&CRYPTO_READ)?"r":"w",file,line); 1260#endif 1261 if (mode & CRYPTO_LOCK) 1262 { 1263 lock_cs[type]->Lock(); 1264 lock_count[type]++; 1265 } 1266 else 1267 { 1268 lock_cs[type]->Unlock(); 1269 } 1270 } 1271 1272void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1273 { 1274 SSL_CTX *ssl_ctx[2]; 1275 thread_id thread_ctx[MAX_THREAD_NUMBER]; 1276 int i; 1277 1278 ssl_ctx[0]=s_ctx; 1279 ssl_ctx[1]=c_ctx; 1280 1281 for (i=0; i<thread_number; i++) 1282 { 1283 thread_ctx[i] = spawn_thread((thread_func)ndoit, 1284 NULL, B_NORMAL_PRIORITY, (void *)ssl_ctx); 1285 resume_thread(thread_ctx[i]); 1286 } 1287 1288 printf("waiting...\n"); 1289 for (i=0; i<thread_number; i++) 1290 { 1291 status_t result; 1292 wait_for_thread(thread_ctx[i], &result); 1293 } 1294 1295 printf("beos threads done (%d,%d)\n", 1296 s_ctx->references,c_ctx->references); 1297 } 1298 1299unsigned long beos_thread_id(void) 1300 { 1301 unsigned long ret; 1302 1303 ret=(unsigned long)find_thread(NULL); 1304 return(ret); 1305 } 1306 1307#endif /* BEOS_THREADS */ 1308