mttest.c 24 KB

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