• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
110 int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *xs);
111 void thread_setup(void);
112 void thread_cleanup(void);
113 void do_threads(SSL_CTX *s_ctx,SSL_CTX *c_ctx);
114 
115 void irix_locking_callback(int mode,int type,char *file,int line);
116 void solaris_locking_callback(int mode,int type,char *file,int line);
117 void win32_locking_callback(int mode,int type,char *file,int line);
118 void pthreads_locking_callback(int mode,int type,char *file,int line);
119 void netware_locking_callback(int mode,int type,char *file,int line);
120 void beos_locking_callback(int mode,int type,const char *file,int line);
121 
122 unsigned long irix_thread_id(void );
123 unsigned long solaris_thread_id(void );
124 unsigned long pthreads_thread_id(void );
125 unsigned long netware_thread_id(void );
126 unsigned long beos_thread_id(void );
127 
128 #if defined(OPENSSL_SYS_NETWARE)
129 static MPKMutex *lock_cs;
130 static MPKSema ThreadSem;
131 static long *lock_count;
132 #endif
133 
134 BIO *bio_err=NULL;
135 BIO *bio_stdout=NULL;
136 
137 static char *cipher=NULL;
138 int verbose=0;
139 #ifdef FIONBIO
140 static int s_nbio=0;
141 #endif
142 
143 int thread_number=10;
144 int number_of_loops=10;
145 int reconnect=0;
146 int cache_stats=0;
147 
148 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
149 
150 int doit(char *ctx[4]);
print_stats(FILE * fp,SSL_CTX * ctx)151 static 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 
sv_usage(void)168 static 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 
main(int argc,char * argv[])186 int 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 		{
267 bad:
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();
336 end:
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 
ndoit(SSL_CTX * ssl_ctx[2])370 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 
doit(char * ctx[4])419 int 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
670 err:
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 
verify_callback(int ok,X509_STORE_CTX * ctx)699 int 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 
724 static HANDLE *lock_cs;
725 
thread_setup(void)726 void 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 
thread_cleanup(void)740 void 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 
win32_locking_callback(int mode,int type,char * file,int line)750 void 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 
do_threads(SSL_CTX * s_ctx,SSL_CTX * c_ctx)762 void 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 
817 static mutex_t *lock_cs;
818 /*static rwlock_t *lock_cs; */
819 static long *lock_count;
820 
thread_setup(void)821 void 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 
thread_cleanup(void)838 void 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 
solaris_locking_callback(int mode,int type,char * file,int line)859 void 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 
do_threads(SSL_CTX * s_ctx,SSL_CTX * c_ctx)891 void 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 
solaris_thread_id(void)920 unsigned 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 
932 static usptr_t *arena;
933 static usema_t **lock_cs;
934 
thread_setup(void)935 void 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 
thread_cleanup(void)960 void 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 
irix_locking_callback(int mode,int type,char * file,int line)976 void 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 
do_threads(SSL_CTX * s_ctx,SSL_CTX * c_ctx)990 void 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 
irix_thread_id(void)1015 unsigned 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 
1026 static pthread_mutex_t *lock_cs;
1027 static long *lock_count;
1028 
thread_setup(void)1029 void 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 
thread_cleanup(void)1045 void 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 
pthreads_locking_callback(int mode,int type,char * file,int line)1063 void 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 
do_threads(SSL_CTX * s_ctx,SSL_CTX * c_ctx)1089 void 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 
pthreads_thread_id(void)1117 unsigned 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 
thread_setup(void)1131 void 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 
thread_cleanup(void)1149 void 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 
netware_locking_callback(int mode,int type,char * file,int line)1170 void 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 
do_threads(SSL_CTX * s_ctx,SSL_CTX * c_ctx)1181 void 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 
netware_thread_id(void)1206 unsigned 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 
1219 static BLocker** lock_cs;
1220 static long* lock_count;
1221 
thread_setup(void)1222 void 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 
thread_cleanup(void)1238 void 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 
beos_locking_callback(int mode,int type,const char * file,int line)1256 void 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 
do_threads(SSL_CTX * s_ctx,SSL_CTX * c_ctx)1275 void 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 
beos_thread_id(void)1302 unsigned 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