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