mttest.c 32 KB

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