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,"%4d client connects (SSL_connect())\n", 156 SSL_CTX_sess_connect(ctx)); 157 fprintf(fp,"%4d client connects that finished\n", 158 SSL_CTX_sess_connect_good(ctx)); 159 fprintf(fp,"%4d server connects (SSL_accept())\n", 160 SSL_CTX_sess_accept(ctx)); 161 fprintf(fp,"%4d server connects that finished\n", 162 SSL_CTX_sess_accept_good(ctx)); 163 fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx)); 164 fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx)); 165 fprintf(fp,"%4d 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 char *scert=TEST_SERVER_CERT; 196 char *ccert=TEST_CLIENT_CERT; 197 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(SSL_CTX_sessions(s_ctx),stderr); 352 fprintf(stderr,"-----\n"); 353 /* lh_node_stats(SSL_CTX_sessions(s_ctx),stderr); 354 fprintf(stderr,"-----\n"); */ 355 lh_node_usage_stats(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 370int 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 c_want,s_want; 431 int i; 432 int done=0; 433 int c_write,s_write; 434 int do_server=0,do_client=0; 435 436 s_ctx=(SSL_CTX *)ctx[0]; 437 c_ctx=(SSL_CTX *)ctx[1]; 438 439 if (ctx[2] != NULL) 440 s_ssl=(SSL *)ctx[2]; 441 else 442 s_ssl=SSL_new(s_ctx); 443 444 if (ctx[3] != NULL) 445 c_ssl=(SSL *)ctx[3]; 446 else 447 c_ssl=SSL_new(c_ctx); 448 449 if ((s_ssl == NULL) || (c_ssl == NULL)) goto err; 450 451 c_to_s=BIO_new(BIO_s_mem()); 452 s_to_c=BIO_new(BIO_s_mem()); 453 if ((s_to_c == NULL) || (c_to_s == NULL)) goto err; 454 455 c_bio=BIO_new(BIO_f_ssl()); 456 s_bio=BIO_new(BIO_f_ssl()); 457 if ((c_bio == NULL) || (s_bio == NULL)) goto err; 458 459 SSL_set_connect_state(c_ssl); 460 SSL_set_bio(c_ssl,s_to_c,c_to_s); 461 BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE); 462 463 SSL_set_accept_state(s_ssl); 464 SSL_set_bio(s_ssl,c_to_s,s_to_c); 465 BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE); 466 467 c_r=0; s_r=1; 468 c_w=1; s_w=0; 469 c_want=W_WRITE; 470 s_want=0; 471 c_write=1,s_write=0; 472 473 /* We can always do writes */ 474 for (;;) 475 { 476 do_server=0; 477 do_client=0; 478 479 i=(int)BIO_pending(s_bio); 480 if ((i && s_r) || s_w) do_server=1; 481 482 i=(int)BIO_pending(c_bio); 483 if ((i && c_r) || c_w) do_client=1; 484 485 if (do_server && verbose) 486 { 487 if (SSL_in_init(s_ssl)) 488 printf("server waiting in SSL_accept - %s\n", 489 SSL_state_string_long(s_ssl)); 490 else if (s_write) 491 printf("server:SSL_write()\n"); 492 else 493 printf("server:SSL_read()\n"); 494 } 495 496 if (do_client && verbose) 497 { 498 if (SSL_in_init(c_ssl)) 499 printf("client waiting in SSL_connect - %s\n", 500 SSL_state_string_long(c_ssl)); 501 else if (c_write) 502 printf("client:SSL_write()\n"); 503 else 504 printf("client:SSL_read()\n"); 505 } 506 507 if (!do_client && !do_server) 508 { 509 fprintf(stdout,"ERROR IN STARTUP\n"); 510 break; 511 } 512 if (do_client && !(done & C_DONE)) 513 { 514 if (c_write) 515 { 516 i=BIO_write(c_bio,"hello from client\n",18); 517 if (i < 0) 518 { 519 c_r=0; 520 c_w=0; 521 if (BIO_should_retry(c_bio)) 522 { 523 if (BIO_should_read(c_bio)) 524 c_r=1; 525 if (BIO_should_write(c_bio)) 526 c_w=1; 527 } 528 else 529 { 530 fprintf(stderr,"ERROR in CLIENT\n"); 531 ERR_print_errors_fp(stderr); 532 return(1); 533 } 534 } 535 else if (i == 0) 536 { 537 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 538 return(1); 539 } 540 else 541 { 542 /* ok */ 543 c_write=0; 544 } 545 } 546 else 547 { 548 i=BIO_read(c_bio,cbuf,100); 549 if (i < 0) 550 { 551 c_r=0; 552 c_w=0; 553 if (BIO_should_retry(c_bio)) 554 { 555 if (BIO_should_read(c_bio)) 556 c_r=1; 557 if (BIO_should_write(c_bio)) 558 c_w=1; 559 } 560 else 561 { 562 fprintf(stderr,"ERROR in CLIENT\n"); 563 ERR_print_errors_fp(stderr); 564 return(1); 565 } 566 } 567 else if (i == 0) 568 { 569 fprintf(stderr,"SSL CLIENT STARTUP FAILED\n"); 570 return(1); 571 } 572 else 573 { 574 done|=C_DONE; 575#ifdef undef 576 fprintf(stdout,"CLIENT:from server:"); 577 fwrite(cbuf,1,i,stdout); 578 fflush(stdout); 579#endif 580 } 581 } 582 } 583 584 if (do_server && !(done & S_DONE)) 585 { 586 if (!s_write) 587 { 588 i=BIO_read(s_bio,sbuf,100); 589 if (i < 0) 590 { 591 s_r=0; 592 s_w=0; 593 if (BIO_should_retry(s_bio)) 594 { 595 if (BIO_should_read(s_bio)) 596 s_r=1; 597 if (BIO_should_write(s_bio)) 598 s_w=1; 599 } 600 else 601 { 602 fprintf(stderr,"ERROR in SERVER\n"); 603 ERR_print_errors_fp(stderr); 604 return(1); 605 } 606 } 607 else if (i == 0) 608 { 609 fprintf(stderr,"SSL SERVER STARTUP FAILED\n"); 610 return(1); 611 } 612 else 613 { 614 s_write=1; 615 s_w=1; 616#ifdef undef 617 fprintf(stdout,"SERVER:from client:"); 618 fwrite(sbuf,1,i,stdout); 619 fflush(stdout); 620#endif 621 } 622 } 623 else 624 { 625 i=BIO_write(s_bio,"hello from server\n",18); 626 if (i < 0) 627 { 628 s_r=0; 629 s_w=0; 630 if (BIO_should_retry(s_bio)) 631 { 632 if (BIO_should_read(s_bio)) 633 s_r=1; 634 if (BIO_should_write(s_bio)) 635 s_w=1; 636 } 637 else 638 { 639 fprintf(stderr,"ERROR in SERVER\n"); 640 ERR_print_errors_fp(stderr); 641 return(1); 642 } 643 } 644 else if (i == 0) 645 { 646 fprintf(stderr,"SSL SERVER STARTUP FAILED\n"); 647 return(1); 648 } 649 else 650 { 651 s_write=0; 652 s_r=1; 653 done|=S_DONE; 654 } 655 } 656 } 657 658 if ((done & S_DONE) && (done & C_DONE)) break; 659# if defined(OPENSSL_SYS_NETWARE) 660 ThreadSwitchWithDelay(); 661# endif 662 } 663 664 SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 665 SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 666 667#ifdef undef 668 fprintf(stdout,"DONE\n"); 669#endif 670err: 671 /* We have to set the BIO's to NULL otherwise they will be 672 * free()ed twice. Once when th s_ssl is SSL_free()ed and 673 * again when c_ssl is SSL_free()ed. 674 * This is a hack required because s_ssl and c_ssl are sharing the same 675 * BIO structure and SSL_set_bio() and SSL_free() automatically 676 * BIO_free non NULL entries. 677 * You should not normally do this or be required to do this */ 678 679 if (s_ssl != NULL) 680 { 681 s_ssl->rbio=NULL; 682 s_ssl->wbio=NULL; 683 } 684 if (c_ssl != NULL) 685 { 686 c_ssl->rbio=NULL; 687 c_ssl->wbio=NULL; 688 } 689 690 /* The SSL's are optionally freed in the following calls */ 691 if (c_to_s != NULL) BIO_free(c_to_s); 692 if (s_to_c != NULL) BIO_free(s_to_c); 693 694 if (c_bio != NULL) BIO_free(c_bio); 695 if (s_bio != NULL) BIO_free(s_bio); 696 return(0); 697 } 698 699int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 700 { 701 char *s, buf[256]; 702 703 if (verbose) 704 { 705 s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), 706 buf,256); 707 if (s != NULL) 708 { 709 if (ok) 710 fprintf(stderr,"depth=%d %s\n", 711 ctx->error_depth,buf); 712 else 713 fprintf(stderr,"depth=%d error=%d %s\n", 714 ctx->error_depth,ctx->error,buf); 715 } 716 } 717 return(ok); 718 } 719 720#define THREAD_STACK_SIZE (16*1024) 721 722#ifdef OPENSSL_SYS_WIN32 723 724static HANDLE *lock_cs; 725 726void thread_setup(void) 727 { 728 int i; 729 730 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); 731 for (i=0; i<CRYPTO_num_locks(); i++) 732 { 733 lock_cs[i]=CreateMutex(NULL,FALSE,NULL); 734 } 735 736 CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback); 737 /* id callback defined */ 738 } 739 740void thread_cleanup(void) 741 { 742 int i; 743 744 CRYPTO_set_locking_callback(NULL); 745 for (i=0; i<CRYPTO_num_locks(); i++) 746 CloseHandle(lock_cs[i]); 747 OPENSSL_free(lock_cs); 748 } 749 750void win32_locking_callback(int mode, int type, char *file, int line) 751 { 752 if (mode & CRYPTO_LOCK) 753 { 754 WaitForSingleObject(lock_cs[type],INFINITE); 755 } 756 else 757 { 758 ReleaseMutex(lock_cs[type]); 759 } 760 } 761 762void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 763 { 764 double ret; 765 SSL_CTX *ssl_ctx[2]; 766 DWORD thread_id[MAX_THREAD_NUMBER]; 767 HANDLE thread_handle[MAX_THREAD_NUMBER]; 768 int i; 769 SYSTEMTIME start,end; 770 771 ssl_ctx[0]=s_ctx; 772 ssl_ctx[1]=c_ctx; 773 774 GetSystemTime(&start); 775 for (i=0; i<thread_number; i++) 776 { 777 thread_handle[i]=CreateThread(NULL, 778 THREAD_STACK_SIZE, 779 (LPTHREAD_START_ROUTINE)ndoit, 780 (void *)ssl_ctx, 781 0L, 782 &(thread_id[i])); 783 } 784 785 printf("reaping\n"); 786 for (i=0; i<thread_number; i+=50) 787 { 788 int j; 789 790 j=(thread_number < (i+50))?(thread_number-i):50; 791 792 if (WaitForMultipleObjects(j, 793 (CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE) 794 == WAIT_FAILED) 795 { 796 fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError()); 797 exit(1); 798 } 799 } 800 GetSystemTime(&end); 801 802 if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7; 803 ret=(end.wDayOfWeek-start.wDayOfWeek)*24; 804 805 ret=(ret+end.wHour-start.wHour)*60; 806 ret=(ret+end.wMinute-start.wMinute)*60; 807 ret=(ret+end.wSecond-start.wSecond); 808 ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0; 809 810 printf("win32 threads done - %.3f seconds\n",ret); 811 } 812 813#endif /* OPENSSL_SYS_WIN32 */ 814 815#ifdef SOLARIS 816 817static mutex_t *lock_cs; 818/*static rwlock_t *lock_cs; */ 819static long *lock_count; 820 821void thread_setup(void) 822 { 823 int i; 824 825 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); 826 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 827 for (i=0; i<CRYPTO_num_locks(); i++) 828 { 829 lock_count[i]=0; 830 /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */ 831 mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL); 832 } 833 834 CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id); 835 CRYPTO_set_locking_callback((void (*)())solaris_locking_callback); 836 } 837 838void thread_cleanup(void) 839 { 840 int i; 841 842 CRYPTO_set_locking_callback(NULL); 843 844 fprintf(stderr,"cleanup\n"); 845 846 for (i=0; i<CRYPTO_num_locks(); i++) 847 { 848 /* rwlock_destroy(&(lock_cs[i])); */ 849 mutex_destroy(&(lock_cs[i])); 850 fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i)); 851 } 852 OPENSSL_free(lock_cs); 853 OPENSSL_free(lock_count); 854 855 fprintf(stderr,"done cleanup\n"); 856 857 } 858 859void solaris_locking_callback(int mode, int type, char *file, int line) 860 { 861#ifdef undef 862 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", 863 CRYPTO_thread_id(), 864 (mode&CRYPTO_LOCK)?"l":"u", 865 (type&CRYPTO_READ)?"r":"w",file,line); 866#endif 867 868 /* 869 if (CRYPTO_LOCK_SSL_CERT == type) 870 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", 871 CRYPTO_thread_id(), 872 mode,file,line); 873 */ 874 if (mode & CRYPTO_LOCK) 875 { 876 /* if (mode & CRYPTO_READ) 877 rw_rdlock(&(lock_cs[type])); 878 else 879 rw_wrlock(&(lock_cs[type])); */ 880 881 mutex_lock(&(lock_cs[type])); 882 lock_count[type]++; 883 } 884 else 885 { 886/* rw_unlock(&(lock_cs[type])); */ 887 mutex_unlock(&(lock_cs[type])); 888 } 889 } 890 891void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 892 { 893 SSL_CTX *ssl_ctx[2]; 894 thread_t thread_ctx[MAX_THREAD_NUMBER]; 895 int i; 896 897 ssl_ctx[0]=s_ctx; 898 ssl_ctx[1]=c_ctx; 899 900 thr_setconcurrency(thread_number); 901 for (i=0; i<thread_number; i++) 902 { 903 thr_create(NULL, THREAD_STACK_SIZE, 904 (void *(*)())ndoit, 905 (void *)ssl_ctx, 906 0L, 907 &(thread_ctx[i])); 908 } 909 910 printf("reaping\n"); 911 for (i=0; i<thread_number; i++) 912 { 913 thr_join(thread_ctx[i],NULL,NULL); 914 } 915 916 printf("solaris threads done (%d,%d)\n", 917 s_ctx->references,c_ctx->references); 918 } 919 920unsigned long solaris_thread_id(void) 921 { 922 unsigned long ret; 923 924 ret=(unsigned long)thr_self(); 925 return(ret); 926 } 927#endif /* SOLARIS */ 928 929#ifdef IRIX 930 931 932static usptr_t *arena; 933static usema_t **lock_cs; 934 935void thread_setup(void) 936 { 937 int i; 938 char filename[20]; 939 940 strcpy(filename,"/tmp/mttest.XXXXXX"); 941 mktemp(filename); 942 943 usconfig(CONF_STHREADIOOFF); 944 usconfig(CONF_STHREADMALLOCOFF); 945 usconfig(CONF_INITUSERS,100); 946 usconfig(CONF_LOCKTYPE,US_DEBUGPLUS); 947 arena=usinit(filename); 948 unlink(filename); 949 950 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); 951 for (i=0; i<CRYPTO_num_locks(); i++) 952 { 953 lock_cs[i]=usnewsema(arena,1); 954 } 955 956 CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id); 957 CRYPTO_set_locking_callback((void (*)())irix_locking_callback); 958 } 959 960void thread_cleanup(void) 961 { 962 int i; 963 964 CRYPTO_set_locking_callback(NULL); 965 for (i=0; i<CRYPTO_num_locks(); i++) 966 { 967 char buf[10]; 968 969 sprintf(buf,"%2d:",i); 970 usdumpsema(lock_cs[i],stdout,buf); 971 usfreesema(lock_cs[i],arena); 972 } 973 OPENSSL_free(lock_cs); 974 } 975 976void irix_locking_callback(int mode, int type, char *file, int line) 977 { 978 if (mode & CRYPTO_LOCK) 979 { 980 printf("lock %d\n",type); 981 uspsema(lock_cs[type]); 982 } 983 else 984 { 985 printf("unlock %d\n",type); 986 usvsema(lock_cs[type]); 987 } 988 } 989 990void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 991 { 992 SSL_CTX *ssl_ctx[2]; 993 int thread_ctx[MAX_THREAD_NUMBER]; 994 int i; 995 996 ssl_ctx[0]=s_ctx; 997 ssl_ctx[1]=c_ctx; 998 999 for (i=0; i<thread_number; i++) 1000 { 1001 thread_ctx[i]=sproc((void (*)())ndoit, 1002 PR_SADDR|PR_SFDS,(void *)ssl_ctx); 1003 } 1004 1005 printf("reaping\n"); 1006 for (i=0; i<thread_number; i++) 1007 { 1008 wait(NULL); 1009 } 1010 1011 printf("irix threads done (%d,%d)\n", 1012 s_ctx->references,c_ctx->references); 1013 } 1014 1015unsigned long irix_thread_id(void) 1016 { 1017 unsigned long ret; 1018 1019 ret=(unsigned long)getpid(); 1020 return(ret); 1021 } 1022#endif /* IRIX */ 1023 1024#ifdef PTHREADS 1025 1026static pthread_mutex_t *lock_cs; 1027static long *lock_count; 1028 1029void thread_setup(void) 1030 { 1031 int i; 1032 1033 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); 1034 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1035 for (i=0; i<CRYPTO_num_locks(); i++) 1036 { 1037 lock_count[i]=0; 1038 pthread_mutex_init(&(lock_cs[i]),NULL); 1039 } 1040 1041 CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); 1042 CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); 1043 } 1044 1045void thread_cleanup(void) 1046 { 1047 int i; 1048 1049 CRYPTO_set_locking_callback(NULL); 1050 fprintf(stderr,"cleanup\n"); 1051 for (i=0; i<CRYPTO_num_locks(); i++) 1052 { 1053 pthread_mutex_destroy(&(lock_cs[i])); 1054 fprintf(stderr,"%8ld:%s\n",lock_count[i], 1055 CRYPTO_get_lock_name(i)); 1056 } 1057 OPENSSL_free(lock_cs); 1058 OPENSSL_free(lock_count); 1059 1060 fprintf(stderr,"done cleanup\n"); 1061 } 1062 1063void pthreads_locking_callback(int mode, int type, char *file, 1064 int line) 1065 { 1066#ifdef undef 1067 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", 1068 CRYPTO_thread_id(), 1069 (mode&CRYPTO_LOCK)?"l":"u", 1070 (type&CRYPTO_READ)?"r":"w",file,line); 1071#endif 1072/* 1073 if (CRYPTO_LOCK_SSL_CERT == type) 1074 fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n", 1075 CRYPTO_thread_id(), 1076 mode,file,line); 1077*/ 1078 if (mode & CRYPTO_LOCK) 1079 { 1080 pthread_mutex_lock(&(lock_cs[type])); 1081 lock_count[type]++; 1082 } 1083 else 1084 { 1085 pthread_mutex_unlock(&(lock_cs[type])); 1086 } 1087 } 1088 1089void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1090 { 1091 SSL_CTX *ssl_ctx[2]; 1092 pthread_t thread_ctx[MAX_THREAD_NUMBER]; 1093 int i; 1094 1095 ssl_ctx[0]=s_ctx; 1096 ssl_ctx[1]=c_ctx; 1097 1098 /* 1099 thr_setconcurrency(thread_number); 1100 */ 1101 for (i=0; i<thread_number; i++) 1102 { 1103 pthread_create(&(thread_ctx[i]), NULL, 1104 (void *(*)())ndoit, (void *)ssl_ctx); 1105 } 1106 1107 printf("reaping\n"); 1108 for (i=0; i<thread_number; i++) 1109 { 1110 pthread_join(thread_ctx[i],NULL); 1111 } 1112 1113 printf("pthreads threads done (%d,%d)\n", 1114 s_ctx->references,c_ctx->references); 1115 } 1116 1117unsigned long pthreads_thread_id(void) 1118 { 1119 unsigned long ret; 1120 1121 ret=(unsigned long)pthread_self(); 1122 return(ret); 1123 } 1124 1125#endif /* PTHREADS */ 1126 1127 1128 1129#ifdef OPENSSL_SYS_NETWARE 1130 1131void thread_setup(void) 1132{ 1133 int i; 1134 1135 lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex)); 1136 lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1137 for (i=0; i<CRYPTO_num_locks(); i++) 1138 { 1139 lock_count[i]=0; 1140 lock_cs[i]=MPKMutexAlloc("OpenSSL mutex"); 1141 } 1142 1143 ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 ); 1144 1145 CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id); 1146 CRYPTO_set_locking_callback((void (*)())netware_locking_callback); 1147} 1148 1149void thread_cleanup(void) 1150{ 1151 int i; 1152 1153 CRYPTO_set_locking_callback(NULL); 1154 1155 fprintf(stdout,"thread_cleanup\n"); 1156 1157 for (i=0; i<CRYPTO_num_locks(); i++) 1158 { 1159 MPKMutexFree(lock_cs[i]); 1160 fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i)); 1161 } 1162 OPENSSL_free(lock_cs); 1163 OPENSSL_free(lock_count); 1164 1165 MPKSemaphoreFree(ThreadSem); 1166 1167 fprintf(stdout,"done cleanup\n"); 1168} 1169 1170void netware_locking_callback(int mode, int type, char *file, int line) 1171{ 1172 if (mode & CRYPTO_LOCK) 1173 { 1174 MPKMutexLock(lock_cs[type]); 1175 lock_count[type]++; 1176 } 1177 else 1178 MPKMutexUnlock(lock_cs[type]); 1179} 1180 1181void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1182{ 1183 SSL_CTX *ssl_ctx[2]; 1184 int i; 1185 ssl_ctx[0]=s_ctx; 1186 ssl_ctx[1]=c_ctx; 1187 1188 for (i=0; i<thread_number; i++) 1189 { 1190 BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE, 1191 (void*)ssl_ctx); 1192 ThreadSwitchWithDelay(); 1193 } 1194 1195 printf("reaping\n"); 1196 1197 /* loop until all threads have signaled the semaphore */ 1198 for (i=0; i<thread_number; i++) 1199 { 1200 MPKSemaphoreWait(ThreadSem); 1201 } 1202 printf("netware threads done (%d,%d)\n", 1203 s_ctx->references,c_ctx->references); 1204} 1205 1206unsigned long netware_thread_id(void) 1207{ 1208 unsigned long ret; 1209 1210 ret=(unsigned long)GetThreadID(); 1211 return(ret); 1212} 1213#endif /* NETWARE */ 1214 1215#ifdef BEOS_THREADS 1216 1217#include <Locker.h> 1218 1219static BLocker** lock_cs; 1220static long* lock_count; 1221 1222void thread_setup(void) 1223 { 1224 int i; 1225 1226 lock_cs=(BLocker**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(BLocker*)); 1227 lock_count=(long*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); 1228 for (i=0; i<CRYPTO_num_locks(); i++) 1229 { 1230 lock_count[i]=0; 1231 lock_cs[i] = new BLocker(CRYPTO_get_lock_name(i)); 1232 } 1233 1234 CRYPTO_set_id_callback((unsigned long (*)())beos_thread_id); 1235 CRYPTO_set_locking_callback(beos_locking_callback); 1236 } 1237 1238void thread_cleanup(void) 1239 { 1240 int i; 1241 1242 CRYPTO_set_locking_callback(NULL); 1243 fprintf(stderr,"cleanup\n"); 1244 for (i=0; i<CRYPTO_num_locks(); i++) 1245 { 1246 delete lock_cs[i]; 1247 fprintf(stderr,"%8ld:%s\n",lock_count[i], 1248 CRYPTO_get_lock_name(i)); 1249 } 1250 OPENSSL_free(lock_cs); 1251 OPENSSL_free(lock_count); 1252 1253 fprintf(stderr,"done cleanup\n"); 1254 } 1255 1256void beos_locking_callback(int mode, int type, const char *file, int line) 1257 { 1258#if 0 1259 fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n", 1260 CRYPTO_thread_id(), 1261 (mode&CRYPTO_LOCK)?"l":"u", 1262 (type&CRYPTO_READ)?"r":"w",file,line); 1263#endif 1264 if (mode & CRYPTO_LOCK) 1265 { 1266 lock_cs[type]->Lock(); 1267 lock_count[type]++; 1268 } 1269 else 1270 { 1271 lock_cs[type]->Unlock(); 1272 } 1273 } 1274 1275void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) 1276 { 1277 SSL_CTX *ssl_ctx[2]; 1278 thread_id thread_ctx[MAX_THREAD_NUMBER]; 1279 int i; 1280 1281 ssl_ctx[0]=s_ctx; 1282 ssl_ctx[1]=c_ctx; 1283 1284 for (i=0; i<thread_number; i++) 1285 { 1286 thread_ctx[i] = spawn_thread((thread_func)ndoit, 1287 NULL, B_NORMAL_PRIORITY, (void *)ssl_ctx); 1288 resume_thread(thread_ctx[i]); 1289 } 1290 1291 printf("waiting...\n"); 1292 for (i=0; i<thread_number; i++) 1293 { 1294 status_t result; 1295 wait_for_thread(thread_ctx[i], &result); 1296 } 1297 1298 printf("beos threads done (%d,%d)\n", 1299 s_ctx->references,c_ctx->references); 1300 } 1301 1302unsigned long beos_thread_id(void) 1303 { 1304 unsigned long ret; 1305 1306 ret=(unsigned long)find_thread(NULL); 1307 return(ret); 1308 } 1309 1310#endif /* BEOS_THREADS */ 1311