• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/ap/gpl/timemachine/openssl-0.9.8e/crypto/threads/
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);
120
121unsigned long irix_thread_id(void );
122unsigned long solaris_thread_id(void );
123unsigned long pthreads_thread_id(void );
124unsigned long netware_thread_id(void );
125
126#if defined(OPENSSL_SYS_NETWARE)
127static MPKMutex *lock_cs;
128static MPKSema ThreadSem;
129static long *lock_count;
130#endif
131
132BIO *bio_err=NULL;
133BIO *bio_stdout=NULL;
134
135static char *cipher=NULL;
136int verbose=0;
137#ifdef FIONBIO
138static int s_nbio=0;
139#endif
140
141int thread_number=10;
142int number_of_loops=10;
143int reconnect=0;
144int cache_stats=0;
145
146static const char rnd_seed[] = "string to make the random number generator think it has entropy";
147
148int doit(char *ctx[4]);
149static void print_stats(FILE *fp, SSL_CTX *ctx)
150{
151	fprintf(fp,"%4ld items in the session cache\n",
152		SSL_CTX_sess_number(ctx));
153	fprintf(fp,"%4d client connects (SSL_connect())\n",
154		SSL_CTX_sess_connect(ctx));
155	fprintf(fp,"%4d client connects that finished\n",
156		SSL_CTX_sess_connect_good(ctx));
157	fprintf(fp,"%4d server connects (SSL_accept())\n",
158		SSL_CTX_sess_accept(ctx));
159	fprintf(fp,"%4d server connects that finished\n",
160		SSL_CTX_sess_accept_good(ctx));
161	fprintf(fp,"%4d session cache hits\n",SSL_CTX_sess_hits(ctx));
162	fprintf(fp,"%4d session cache misses\n",SSL_CTX_sess_misses(ctx));
163	fprintf(fp,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ctx));
164	}
165
166static void sv_usage(void)
167	{
168	fprintf(stderr,"usage: ssltest [args ...]\n");
169	fprintf(stderr,"\n");
170	fprintf(stderr," -server_auth  - check server certificate\n");
171	fprintf(stderr," -client_auth  - do client authentication\n");
172	fprintf(stderr," -v            - more output\n");
173	fprintf(stderr," -CApath arg   - PEM format directory of CA's\n");
174	fprintf(stderr," -CAfile arg   - PEM format file of CA's\n");
175	fprintf(stderr," -threads arg  - number of threads\n");
176	fprintf(stderr," -loops arg    - number of 'connections', per thread\n");
177	fprintf(stderr," -reconnect    - reuse session-id's\n");
178	fprintf(stderr," -stats        - server session-id cache stats\n");
179	fprintf(stderr," -cert arg     - server certificate/key\n");
180	fprintf(stderr," -ccert arg    - client certificate/key\n");
181	fprintf(stderr," -ssl3         - just SSLv3n\n");
182	}
183
184int main(int argc, char *argv[])
185	{
186	char *CApath=NULL,*CAfile=NULL;
187	int badop=0;
188	int ret=1;
189	int client_auth=0;
190	int server_auth=0;
191	SSL_CTX *s_ctx=NULL;
192	SSL_CTX *c_ctx=NULL;
193	char *scert=TEST_SERVER_CERT;
194	char *ccert=TEST_CLIENT_CERT;
195	SSL_METHOD *ssl_method=SSLv23_method();
196
197	RAND_seed(rnd_seed, sizeof rnd_seed);
198
199	if (bio_err == NULL)
200		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
201	if (bio_stdout == NULL)
202		bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
203	argc--;
204	argv++;
205
206	while (argc >= 1)
207		{
208		if	(strcmp(*argv,"-server_auth") == 0)
209			server_auth=1;
210		else if	(strcmp(*argv,"-client_auth") == 0)
211			client_auth=1;
212		else if	(strcmp(*argv,"-reconnect") == 0)
213			reconnect=1;
214		else if	(strcmp(*argv,"-stats") == 0)
215			cache_stats=1;
216		else if	(strcmp(*argv,"-ssl3") == 0)
217			ssl_method=SSLv3_method();
218		else if	(strcmp(*argv,"-ssl2") == 0)
219			ssl_method=SSLv2_method();
220		else if	(strcmp(*argv,"-CApath") == 0)
221			{
222			if (--argc < 1) goto bad;
223			CApath= *(++argv);
224			}
225		else if	(strcmp(*argv,"-CAfile") == 0)
226			{
227			if (--argc < 1) goto bad;
228			CAfile= *(++argv);
229			}
230		else if	(strcmp(*argv,"-cert") == 0)
231			{
232			if (--argc < 1) goto bad;
233			scert= *(++argv);
234			}
235		else if	(strcmp(*argv,"-ccert") == 0)
236			{
237			if (--argc < 1) goto bad;
238			ccert= *(++argv);
239			}
240		else if	(strcmp(*argv,"-threads") == 0)
241			{
242			if (--argc < 1) goto bad;
243			thread_number= atoi(*(++argv));
244			if (thread_number == 0) thread_number=1;
245			if (thread_number > MAX_THREAD_NUMBER)
246				thread_number=MAX_THREAD_NUMBER;
247			}
248		else if	(strcmp(*argv,"-loops") == 0)
249			{
250			if (--argc < 1) goto bad;
251			number_of_loops= atoi(*(++argv));
252			if (number_of_loops == 0) number_of_loops=1;
253			}
254		else
255			{
256			fprintf(stderr,"unknown option %s\n",*argv);
257			badop=1;
258			break;
259			}
260		argc--;
261		argv++;
262		}
263	if (badop)
264		{
265bad:
266		sv_usage();
267		goto end;
268		}
269
270	if (cipher == NULL && OPENSSL_issetugid() == 0)
271		cipher=getenv("SSL_CIPHER");
272
273	SSL_load_error_strings();
274	OpenSSL_add_ssl_algorithms();
275
276	c_ctx=SSL_CTX_new(ssl_method);
277	s_ctx=SSL_CTX_new(ssl_method);
278	if ((c_ctx == NULL) || (s_ctx == NULL))
279		{
280		ERR_print_errors(bio_err);
281		goto end;
282		}
283
284	SSL_CTX_set_session_cache_mode(s_ctx,
285		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
286	SSL_CTX_set_session_cache_mode(c_ctx,
287		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
288
289	if (!SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM))
290		{
291		ERR_print_errors(bio_err);
292		}
293	else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM))
294		{
295		ERR_print_errors(bio_err);
296		goto end;
297		}
298
299	if (client_auth)
300		{
301		SSL_CTX_use_certificate_file(c_ctx,ccert,
302			SSL_FILETYPE_PEM);
303		SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
304			SSL_FILETYPE_PEM);
305		}
306
307	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
308		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
309		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
310		(!SSL_CTX_set_default_verify_paths(c_ctx)))
311		{
312		fprintf(stderr,"SSL_load_verify_locations\n");
313		ERR_print_errors(bio_err);
314		goto end;
315		}
316
317	if (client_auth)
318		{
319		fprintf(stderr,"client authentication\n");
320		SSL_CTX_set_verify(s_ctx,
321			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
322			verify_callback);
323		}
324	if (server_auth)
325		{
326		fprintf(stderr,"server authentication\n");
327		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
328			verify_callback);
329		}
330
331	thread_setup();
332	do_threads(s_ctx,c_ctx);
333	thread_cleanup();
334end:
335
336	if (c_ctx != NULL)
337		{
338		fprintf(stderr,"Client SSL_CTX stats then free it\n");
339		print_stats(stderr,c_ctx);
340		SSL_CTX_free(c_ctx);
341		}
342	if (s_ctx != NULL)
343		{
344		fprintf(stderr,"Server SSL_CTX stats then free it\n");
345		print_stats(stderr,s_ctx);
346		if (cache_stats)
347			{
348			fprintf(stderr,"-----\n");
349			lh_stats(SSL_CTX_sessions(s_ctx),stderr);
350			fprintf(stderr,"-----\n");
351		/*	lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
352			fprintf(stderr,"-----\n"); */
353			lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
354			fprintf(stderr,"-----\n");
355			}
356		SSL_CTX_free(s_ctx);
357		fprintf(stderr,"done free\n");
358		}
359	exit(ret);
360	return(0);
361	}
362
363#define W_READ	1
364#define W_WRITE	2
365#define C_DONE	1
366#define S_DONE	2
367
368int ndoit(SSL_CTX *ssl_ctx[2])
369	{
370	int i;
371	int ret;
372	char *ctx[4];
373
374	ctx[0]=(char *)ssl_ctx[0];
375	ctx[1]=(char *)ssl_ctx[1];
376
377	if (reconnect)
378		{
379		ctx[2]=(char *)SSL_new(ssl_ctx[0]);
380		ctx[3]=(char *)SSL_new(ssl_ctx[1]);
381		}
382	else
383		{
384		ctx[2]=NULL;
385		ctx[3]=NULL;
386		}
387
388	fprintf(stdout,"started thread %lu\n",CRYPTO_thread_id());
389	for (i=0; i<number_of_loops; i++)
390		{
391/*		fprintf(stderr,"%4d %2d ctx->ref (%3d,%3d)\n",
392			CRYPTO_thread_id(),i,
393			ssl_ctx[0]->references,
394			ssl_ctx[1]->references); */
395	/*	pthread_delay_np(&tm);*/
396
397		ret=doit(ctx);
398		if (ret != 0)
399			{
400			fprintf(stdout,"error[%d] %lu - %d\n",
401				i,CRYPTO_thread_id(),ret);
402			return(ret);
403			}
404		}
405	fprintf(stdout,"DONE %lu\n",CRYPTO_thread_id());
406	if (reconnect)
407		{
408		SSL_free((SSL *)ctx[2]);
409		SSL_free((SSL *)ctx[3]);
410		}
411#   ifdef OPENSSL_SYS_NETWARE
412        MPKSemaphoreSignal(ThreadSem);
413#   endif
414	return(0);
415	}
416
417int doit(char *ctx[4])
418	{
419	SSL_CTX *s_ctx,*c_ctx;
420	static char cbuf[200],sbuf[200];
421	SSL *c_ssl=NULL;
422	SSL *s_ssl=NULL;
423	BIO *c_to_s=NULL;
424	BIO *s_to_c=NULL;
425	BIO *c_bio=NULL;
426	BIO *s_bio=NULL;
427	int c_r,c_w,s_r,s_w;
428	int c_want,s_want;
429	int i;
430	int done=0;
431	int c_write,s_write;
432	int do_server=0,do_client=0;
433
434	s_ctx=(SSL_CTX *)ctx[0];
435	c_ctx=(SSL_CTX *)ctx[1];
436
437	if (ctx[2] != NULL)
438		s_ssl=(SSL *)ctx[2];
439	else
440		s_ssl=SSL_new(s_ctx);
441
442	if (ctx[3] != NULL)
443		c_ssl=(SSL *)ctx[3];
444	else
445		c_ssl=SSL_new(c_ctx);
446
447	if ((s_ssl == NULL) || (c_ssl == NULL)) goto err;
448
449	c_to_s=BIO_new(BIO_s_mem());
450	s_to_c=BIO_new(BIO_s_mem());
451	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
452
453	c_bio=BIO_new(BIO_f_ssl());
454	s_bio=BIO_new(BIO_f_ssl());
455	if ((c_bio == NULL) || (s_bio == NULL)) goto err;
456
457	SSL_set_connect_state(c_ssl);
458	SSL_set_bio(c_ssl,s_to_c,c_to_s);
459	BIO_set_ssl(c_bio,c_ssl,(ctx[2] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
460
461	SSL_set_accept_state(s_ssl);
462	SSL_set_bio(s_ssl,c_to_s,s_to_c);
463	BIO_set_ssl(s_bio,s_ssl,(ctx[3] == NULL)?BIO_CLOSE:BIO_NOCLOSE);
464
465	c_r=0; s_r=1;
466	c_w=1; s_w=0;
467	c_want=W_WRITE;
468	s_want=0;
469	c_write=1,s_write=0;
470
471	/* We can always do writes */
472	for (;;)
473		{
474		do_server=0;
475		do_client=0;
476
477		i=(int)BIO_pending(s_bio);
478		if ((i && s_r) || s_w) do_server=1;
479
480		i=(int)BIO_pending(c_bio);
481		if ((i && c_r) || c_w) do_client=1;
482
483		if (do_server && verbose)
484			{
485			if (SSL_in_init(s_ssl))
486				printf("server waiting in SSL_accept - %s\n",
487					SSL_state_string_long(s_ssl));
488			else if (s_write)
489				printf("server:SSL_write()\n");
490			else
491				printf("server:SSL_read()\n");
492			}
493
494		if (do_client && verbose)
495			{
496			if (SSL_in_init(c_ssl))
497				printf("client waiting in SSL_connect - %s\n",
498					SSL_state_string_long(c_ssl));
499			else if (c_write)
500				printf("client:SSL_write()\n");
501			else
502				printf("client:SSL_read()\n");
503			}
504
505		if (!do_client && !do_server)
506			{
507			fprintf(stdout,"ERROR IN STARTUP\n");
508			break;
509			}
510		if (do_client && !(done & C_DONE))
511			{
512			if (c_write)
513				{
514				i=BIO_write(c_bio,"hello from client\n",18);
515				if (i < 0)
516					{
517					c_r=0;
518					c_w=0;
519					if (BIO_should_retry(c_bio))
520						{
521						if (BIO_should_read(c_bio))
522							c_r=1;
523						if (BIO_should_write(c_bio))
524							c_w=1;
525						}
526					else
527						{
528						fprintf(stderr,"ERROR in CLIENT\n");
529						ERR_print_errors_fp(stderr);
530						return(1);
531						}
532					}
533				else if (i == 0)
534					{
535					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
536					return(1);
537					}
538				else
539					{
540					/* ok */
541					c_write=0;
542					}
543				}
544			else
545				{
546				i=BIO_read(c_bio,cbuf,100);
547				if (i < 0)
548					{
549					c_r=0;
550					c_w=0;
551					if (BIO_should_retry(c_bio))
552						{
553						if (BIO_should_read(c_bio))
554							c_r=1;
555						if (BIO_should_write(c_bio))
556							c_w=1;
557						}
558					else
559						{
560						fprintf(stderr,"ERROR in CLIENT\n");
561						ERR_print_errors_fp(stderr);
562						return(1);
563						}
564					}
565				else if (i == 0)
566					{
567					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
568					return(1);
569					}
570				else
571					{
572					done|=C_DONE;
573#ifdef undef
574					fprintf(stdout,"CLIENT:from server:");
575					fwrite(cbuf,1,i,stdout);
576					fflush(stdout);
577#endif
578					}
579				}
580			}
581
582		if (do_server && !(done & S_DONE))
583			{
584			if (!s_write)
585				{
586				i=BIO_read(s_bio,sbuf,100);
587				if (i < 0)
588					{
589					s_r=0;
590					s_w=0;
591					if (BIO_should_retry(s_bio))
592						{
593						if (BIO_should_read(s_bio))
594							s_r=1;
595						if (BIO_should_write(s_bio))
596							s_w=1;
597						}
598					else
599						{
600						fprintf(stderr,"ERROR in SERVER\n");
601						ERR_print_errors_fp(stderr);
602						return(1);
603						}
604					}
605				else if (i == 0)
606					{
607					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
608					return(1);
609					}
610				else
611					{
612					s_write=1;
613					s_w=1;
614#ifdef undef
615					fprintf(stdout,"SERVER:from client:");
616					fwrite(sbuf,1,i,stdout);
617					fflush(stdout);
618#endif
619					}
620				}
621			else
622				{
623				i=BIO_write(s_bio,"hello from server\n",18);
624				if (i < 0)
625					{
626					s_r=0;
627					s_w=0;
628					if (BIO_should_retry(s_bio))
629						{
630						if (BIO_should_read(s_bio))
631							s_r=1;
632						if (BIO_should_write(s_bio))
633							s_w=1;
634						}
635					else
636						{
637						fprintf(stderr,"ERROR in SERVER\n");
638						ERR_print_errors_fp(stderr);
639						return(1);
640						}
641					}
642				else if (i == 0)
643					{
644					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
645					return(1);
646					}
647				else
648					{
649					s_write=0;
650					s_r=1;
651					done|=S_DONE;
652					}
653				}
654			}
655
656		if ((done & S_DONE) && (done & C_DONE)) break;
657#   if defined(OPENSSL_SYS_NETWARE)
658        ThreadSwitchWithDelay();
659#   endif
660		}
661
662	SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
663	SSL_set_shutdown(s_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
664
665#ifdef undef
666	fprintf(stdout,"DONE\n");
667#endif
668err:
669	/* We have to set the BIO's to NULL otherwise they will be
670	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
671	 * again when c_ssl is SSL_free()ed.
672	 * This is a hack required because s_ssl and c_ssl are sharing the same
673	 * BIO structure and SSL_set_bio() and SSL_free() automatically
674	 * BIO_free non NULL entries.
675	 * You should not normally do this or be required to do this */
676
677	if (s_ssl != NULL)
678		{
679		s_ssl->rbio=NULL;
680		s_ssl->wbio=NULL;
681		}
682	if (c_ssl != NULL)
683		{
684		c_ssl->rbio=NULL;
685		c_ssl->wbio=NULL;
686		}
687
688	/* The SSL's are optionally freed in the following calls */
689	if (c_to_s != NULL) BIO_free(c_to_s);
690	if (s_to_c != NULL) BIO_free(s_to_c);
691
692	if (c_bio != NULL) BIO_free(c_bio);
693	if (s_bio != NULL) BIO_free(s_bio);
694	return(0);
695	}
696
697int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
698	{
699	char *s, buf[256];
700
701	if (verbose)
702		{
703		s=X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
704				    buf,256);
705		if (s != NULL)
706			{
707			if (ok)
708				fprintf(stderr,"depth=%d %s\n",
709					ctx->error_depth,buf);
710			else
711				fprintf(stderr,"depth=%d error=%d %s\n",
712					ctx->error_depth,ctx->error,buf);
713			}
714		}
715	return(ok);
716	}
717
718#define THREAD_STACK_SIZE (16*1024)
719
720#ifdef OPENSSL_SYS_WIN32
721
722static HANDLE *lock_cs;
723
724void thread_setup(void)
725	{
726	int i;
727
728	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
729	for (i=0; i<CRYPTO_num_locks(); i++)
730		{
731		lock_cs[i]=CreateMutex(NULL,FALSE,NULL);
732		}
733
734	CRYPTO_set_locking_callback((void (*)(int,int,char *,int))win32_locking_callback);
735	/* id callback defined */
736	}
737
738void thread_cleanup(void)
739	{
740	int i;
741
742	CRYPTO_set_locking_callback(NULL);
743	for (i=0; i<CRYPTO_num_locks(); i++)
744		CloseHandle(lock_cs[i]);
745	OPENSSL_free(lock_cs);
746	}
747
748void win32_locking_callback(int mode, int type, char *file, int line)
749	{
750	if (mode & CRYPTO_LOCK)
751		{
752		WaitForSingleObject(lock_cs[type],INFINITE);
753		}
754	else
755		{
756		ReleaseMutex(lock_cs[type]);
757		}
758	}
759
760void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
761	{
762	double ret;
763	SSL_CTX *ssl_ctx[2];
764	DWORD thread_id[MAX_THREAD_NUMBER];
765	HANDLE thread_handle[MAX_THREAD_NUMBER];
766	int i;
767	SYSTEMTIME start,end;
768
769	ssl_ctx[0]=s_ctx;
770	ssl_ctx[1]=c_ctx;
771
772	GetSystemTime(&start);
773	for (i=0; i<thread_number; i++)
774		{
775		thread_handle[i]=CreateThread(NULL,
776			THREAD_STACK_SIZE,
777			(LPTHREAD_START_ROUTINE)ndoit,
778			(void *)ssl_ctx,
779			0L,
780			&(thread_id[i]));
781		}
782
783	printf("reaping\n");
784	for (i=0; i<thread_number; i+=50)
785		{
786		int j;
787
788		j=(thread_number < (i+50))?(thread_number-i):50;
789
790		if (WaitForMultipleObjects(j,
791			(CONST HANDLE *)&(thread_handle[i]),TRUE,INFINITE)
792			== WAIT_FAILED)
793			{
794			fprintf(stderr,"WaitForMultipleObjects failed:%d\n",GetLastError());
795			exit(1);
796			}
797		}
798	GetSystemTime(&end);
799
800	if (start.wDayOfWeek > end.wDayOfWeek) end.wDayOfWeek+=7;
801	ret=(end.wDayOfWeek-start.wDayOfWeek)*24;
802
803	ret=(ret+end.wHour-start.wHour)*60;
804	ret=(ret+end.wMinute-start.wMinute)*60;
805	ret=(ret+end.wSecond-start.wSecond);
806	ret+=(end.wMilliseconds-start.wMilliseconds)/1000.0;
807
808	printf("win32 threads done - %.3f seconds\n",ret);
809	}
810
811#endif /* OPENSSL_SYS_WIN32 */
812
813#ifdef SOLARIS
814
815static mutex_t *lock_cs;
816/*static rwlock_t *lock_cs; */
817static long *lock_count;
818
819void thread_setup(void)
820	{
821	int i;
822
823	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t));
824	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
825	for (i=0; i<CRYPTO_num_locks(); i++)
826		{
827		lock_count[i]=0;
828		/* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */
829		mutex_init(&(lock_cs[i]),USYNC_THREAD,NULL);
830		}
831
832	CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id);
833	CRYPTO_set_locking_callback((void (*)())solaris_locking_callback);
834	}
835
836void thread_cleanup(void)
837	{
838	int i;
839
840	CRYPTO_set_locking_callback(NULL);
841
842	fprintf(stderr,"cleanup\n");
843
844	for (i=0; i<CRYPTO_num_locks(); i++)
845		{
846		/* rwlock_destroy(&(lock_cs[i])); */
847		mutex_destroy(&(lock_cs[i]));
848		fprintf(stderr,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
849		}
850	OPENSSL_free(lock_cs);
851	OPENSSL_free(lock_count);
852
853	fprintf(stderr,"done cleanup\n");
854
855	}
856
857void solaris_locking_callback(int mode, int type, char *file, int line)
858	{
859#ifdef undef
860	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
861		CRYPTO_thread_id(),
862		(mode&CRYPTO_LOCK)?"l":"u",
863		(type&CRYPTO_READ)?"r":"w",file,line);
864#endif
865
866	/*
867	if (CRYPTO_LOCK_SSL_CERT == type)
868	fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
869		CRYPTO_thread_id(),
870		mode,file,line);
871	*/
872	if (mode & CRYPTO_LOCK)
873		{
874	/*	if (mode & CRYPTO_READ)
875			rw_rdlock(&(lock_cs[type]));
876		else
877			rw_wrlock(&(lock_cs[type])); */
878
879		mutex_lock(&(lock_cs[type]));
880		lock_count[type]++;
881		}
882	else
883		{
884/*		rw_unlock(&(lock_cs[type]));  */
885		mutex_unlock(&(lock_cs[type]));
886		}
887	}
888
889void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
890	{
891	SSL_CTX *ssl_ctx[2];
892	thread_t thread_ctx[MAX_THREAD_NUMBER];
893	int i;
894
895	ssl_ctx[0]=s_ctx;
896	ssl_ctx[1]=c_ctx;
897
898	thr_setconcurrency(thread_number);
899	for (i=0; i<thread_number; i++)
900		{
901		thr_create(NULL, THREAD_STACK_SIZE,
902			(void *(*)())ndoit,
903			(void *)ssl_ctx,
904			0L,
905			&(thread_ctx[i]));
906		}
907
908	printf("reaping\n");
909	for (i=0; i<thread_number; i++)
910		{
911		thr_join(thread_ctx[i],NULL,NULL);
912		}
913
914	printf("solaris threads done (%d,%d)\n",
915		s_ctx->references,c_ctx->references);
916	}
917
918unsigned long solaris_thread_id(void)
919	{
920	unsigned long ret;
921
922	ret=(unsigned long)thr_self();
923	return(ret);
924	}
925#endif /* SOLARIS */
926
927#ifdef IRIX
928
929
930static usptr_t *arena;
931static usema_t **lock_cs;
932
933void thread_setup(void)
934	{
935	int i;
936	char filename[20];
937
938	strcpy(filename,"/tmp/mttest.XXXXXX");
939	mktemp(filename);
940
941	usconfig(CONF_STHREADIOOFF);
942	usconfig(CONF_STHREADMALLOCOFF);
943	usconfig(CONF_INITUSERS,100);
944	usconfig(CONF_LOCKTYPE,US_DEBUGPLUS);
945	arena=usinit(filename);
946	unlink(filename);
947
948	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *));
949	for (i=0; i<CRYPTO_num_locks(); i++)
950		{
951		lock_cs[i]=usnewsema(arena,1);
952		}
953
954	CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id);
955	CRYPTO_set_locking_callback((void (*)())irix_locking_callback);
956	}
957
958void thread_cleanup(void)
959	{
960	int i;
961
962	CRYPTO_set_locking_callback(NULL);
963	for (i=0; i<CRYPTO_num_locks(); i++)
964		{
965		char buf[10];
966
967		sprintf(buf,"%2d:",i);
968		usdumpsema(lock_cs[i],stdout,buf);
969		usfreesema(lock_cs[i],arena);
970		}
971	OPENSSL_free(lock_cs);
972	}
973
974void irix_locking_callback(int mode, int type, char *file, int line)
975	{
976	if (mode & CRYPTO_LOCK)
977		{
978		printf("lock %d\n",type);
979		uspsema(lock_cs[type]);
980		}
981	else
982		{
983		printf("unlock %d\n",type);
984		usvsema(lock_cs[type]);
985		}
986	}
987
988void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
989	{
990	SSL_CTX *ssl_ctx[2];
991	int thread_ctx[MAX_THREAD_NUMBER];
992	int i;
993
994	ssl_ctx[0]=s_ctx;
995	ssl_ctx[1]=c_ctx;
996
997	for (i=0; i<thread_number; i++)
998		{
999		thread_ctx[i]=sproc((void (*)())ndoit,
1000			PR_SADDR|PR_SFDS,(void *)ssl_ctx);
1001		}
1002
1003	printf("reaping\n");
1004	for (i=0; i<thread_number; i++)
1005		{
1006		wait(NULL);
1007		}
1008
1009	printf("irix threads done (%d,%d)\n",
1010		s_ctx->references,c_ctx->references);
1011	}
1012
1013unsigned long irix_thread_id(void)
1014	{
1015	unsigned long ret;
1016
1017	ret=(unsigned long)getpid();
1018	return(ret);
1019	}
1020#endif /* IRIX */
1021
1022#ifdef PTHREADS
1023
1024static pthread_mutex_t *lock_cs;
1025static long *lock_count;
1026
1027void thread_setup(void)
1028	{
1029	int i;
1030
1031	lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
1032	lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
1033	for (i=0; i<CRYPTO_num_locks(); i++)
1034		{
1035		lock_count[i]=0;
1036		pthread_mutex_init(&(lock_cs[i]),NULL);
1037		}
1038
1039	CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
1040	CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
1041	}
1042
1043void thread_cleanup(void)
1044	{
1045	int i;
1046
1047	CRYPTO_set_locking_callback(NULL);
1048	fprintf(stderr,"cleanup\n");
1049	for (i=0; i<CRYPTO_num_locks(); i++)
1050		{
1051		pthread_mutex_destroy(&(lock_cs[i]));
1052		fprintf(stderr,"%8ld:%s\n",lock_count[i],
1053			CRYPTO_get_lock_name(i));
1054		}
1055	OPENSSL_free(lock_cs);
1056	OPENSSL_free(lock_count);
1057
1058	fprintf(stderr,"done cleanup\n");
1059	}
1060
1061void pthreads_locking_callback(int mode, int type, char *file,
1062	     int line)
1063      {
1064#ifdef undef
1065	fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
1066		CRYPTO_thread_id(),
1067		(mode&CRYPTO_LOCK)?"l":"u",
1068		(type&CRYPTO_READ)?"r":"w",file,line);
1069#endif
1070/*
1071	if (CRYPTO_LOCK_SSL_CERT == type)
1072		fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
1073		CRYPTO_thread_id(),
1074		mode,file,line);
1075*/
1076	if (mode & CRYPTO_LOCK)
1077		{
1078		pthread_mutex_lock(&(lock_cs[type]));
1079		lock_count[type]++;
1080		}
1081	else
1082		{
1083		pthread_mutex_unlock(&(lock_cs[type]));
1084		}
1085	}
1086
1087void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
1088	{
1089	SSL_CTX *ssl_ctx[2];
1090	pthread_t thread_ctx[MAX_THREAD_NUMBER];
1091	int i;
1092
1093	ssl_ctx[0]=s_ctx;
1094	ssl_ctx[1]=c_ctx;
1095
1096	/*
1097	thr_setconcurrency(thread_number);
1098	*/
1099	for (i=0; i<thread_number; i++)
1100		{
1101		pthread_create(&(thread_ctx[i]), NULL,
1102			(void *(*)())ndoit, (void *)ssl_ctx);
1103		}
1104
1105	printf("reaping\n");
1106	for (i=0; i<thread_number; i++)
1107		{
1108		pthread_join(thread_ctx[i],NULL);
1109		}
1110
1111	printf("pthreads threads done (%d,%d)\n",
1112		s_ctx->references,c_ctx->references);
1113	}
1114
1115unsigned long pthreads_thread_id(void)
1116	{
1117	unsigned long ret;
1118
1119	ret=(unsigned long)pthread_self();
1120	return(ret);
1121	}
1122
1123#endif /* PTHREADS */
1124
1125
1126
1127#ifdef OPENSSL_SYS_NETWARE
1128
1129void thread_setup(void)
1130{
1131   int i;
1132
1133   lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex));
1134   lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
1135   for (i=0; i<CRYPTO_num_locks(); i++)
1136   {
1137      lock_count[i]=0;
1138      lock_cs[i]=MPKMutexAlloc("OpenSSL mutex");
1139   }
1140
1141   ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 );
1142
1143   CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id);
1144   CRYPTO_set_locking_callback((void (*)())netware_locking_callback);
1145}
1146
1147void thread_cleanup(void)
1148{
1149   int i;
1150
1151   CRYPTO_set_locking_callback(NULL);
1152
1153   fprintf(stdout,"thread_cleanup\n");
1154
1155   for (i=0; i<CRYPTO_num_locks(); i++)
1156   {
1157      MPKMutexFree(lock_cs[i]);
1158      fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
1159   }
1160   OPENSSL_free(lock_cs);
1161   OPENSSL_free(lock_count);
1162
1163   MPKSemaphoreFree(ThreadSem);
1164
1165   fprintf(stdout,"done cleanup\n");
1166}
1167
1168void netware_locking_callback(int mode, int type, char *file, int line)
1169{
1170   if (mode & CRYPTO_LOCK)
1171   {
1172      MPKMutexLock(lock_cs[type]);
1173      lock_count[type]++;
1174   }
1175   else
1176      MPKMutexUnlock(lock_cs[type]);
1177}
1178
1179void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
1180{
1181   SSL_CTX *ssl_ctx[2];
1182   int i;
1183   ssl_ctx[0]=s_ctx;
1184   ssl_ctx[1]=c_ctx;
1185
1186   for (i=0; i<thread_number; i++)
1187   {
1188      BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE,
1189                   (void*)ssl_ctx);
1190      ThreadSwitchWithDelay();
1191   }
1192
1193   printf("reaping\n");
1194
1195      /* loop until all threads have signaled the semaphore */
1196   for (i=0; i<thread_number; i++)
1197   {
1198      MPKSemaphoreWait(ThreadSem);
1199   }
1200   printf("netware threads done (%d,%d)\n",
1201         s_ctx->references,c_ctx->references);
1202}
1203
1204unsigned long netware_thread_id(void)
1205{
1206   unsigned long ret;
1207
1208   ret=(unsigned long)GetThreadID();
1209   return(ret);
1210}
1211#endif /* NETWARE */
1212