testsuite.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /* testsuite.c
  2. *
  3. * Copyright (C) 2006-2022 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #include <wolfssl/wolfcrypt/settings.h>
  25. #include <wolfssl/ssl.h>
  26. #include <wolfssl/test.h>
  27. #include <wolfcrypt/test/test.h>
  28. #ifndef SINGLE_THREADED
  29. #ifdef OPENSSL_EXTRA
  30. #include <wolfssl/openssl/ssl.h>
  31. #endif
  32. #include <wolfssl/wolfcrypt/sha256.h>
  33. #include <wolfssl/wolfcrypt/ecc.h>
  34. #include <examples/echoclient/echoclient.h>
  35. #include <examples/echoserver/echoserver.h>
  36. #include <examples/server/server.h>
  37. #include <examples/client/client.h>
  38. #ifndef NO_SHA256
  39. void file_test(const char* file, byte* check);
  40. #endif
  41. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT)
  42. #ifdef HAVE_STACK_SIZE
  43. static THREAD_RETURN simple_test(func_args *args);
  44. #else
  45. static void simple_test(func_args *args);
  46. #endif
  47. static int test_tls(func_args* server_args);
  48. static void show_ciphers(void);
  49. static void cleanup_output(void);
  50. static int validate_cleanup_output(void);
  51. enum {
  52. NUMARGS = 3
  53. };
  54. static const char *outputName;
  55. #endif
  56. int myoptind = 0;
  57. char* myoptarg = NULL;
  58. #ifndef NO_TESTSUITE_MAIN_DRIVER
  59. static int testsuite_test(int argc, char** argv);
  60. int main(int argc, char** argv)
  61. {
  62. return testsuite_test(argc, argv);
  63. }
  64. #endif /* NO_TESTSUITE_MAIN_DRIVER */
  65. #ifdef HAVE_STACK_SIZE
  66. /* Wrap TLS echo client to free thread locals. */
  67. static void *echoclient_test_wrapper(void* args) {
  68. echoclient_test(args);
  69. #if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
  70. wc_ecc_fp_free(); /* free per thread cache */
  71. #endif
  72. return (void *)0;
  73. }
  74. #endif
  75. int testsuite_test(int argc, char** argv)
  76. {
  77. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  78. (!defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLF_CRYPTO_CB_ONLY_ECC))
  79. func_args server_args;
  80. tcp_ready ready;
  81. #if !defined(NETOS)
  82. THREAD_TYPE serverThread;
  83. int ret;
  84. #endif
  85. #ifndef USE_WINDOWS_API
  86. const char *tempDir = NULL;
  87. char tempName[128];
  88. int tempName_len;
  89. int tempName_Xnum;
  90. #else
  91. char tempName[] = "fnXXXXXX";
  92. const int tempName_len = 8;
  93. const int tempName_Xnum = 6;
  94. #endif
  95. #ifdef HAVE_STACK_SIZE
  96. void *serverThreadStackContext = NULL;
  97. #endif
  98. #ifndef USE_WINDOWS_API
  99. #ifdef XGETENV
  100. tempDir = XGETENV("TMPDIR");
  101. if (tempDir == NULL)
  102. #endif
  103. {
  104. tempDir = "/tmp";
  105. }
  106. XSTRLCPY(tempName, tempDir, sizeof(tempName));
  107. XSTRLCAT(tempName, "/testsuite-output-XXXXXX", sizeof(tempName));
  108. tempName_len = (int)XSTRLEN(tempName);
  109. tempName_Xnum = 6;
  110. #endif /* !USE_WINDOWS_API */
  111. #ifdef HAVE_WNR
  112. if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0) {
  113. err_sys("Whitewood netRandom global config failed");
  114. return -1237;
  115. }
  116. #endif /* HAVE_WNR */
  117. StartTCP();
  118. server_args.argc = argc;
  119. server_args.argv = argv;
  120. wolfSSL_Init();
  121. #if defined(DEBUG_WOLFSSL) && !defined(HAVE_VALGRIND)
  122. wolfSSL_Debugging_ON();
  123. #endif
  124. #if !defined(WOLFSSL_TIRTOS)
  125. ChangeToWolfRoot();
  126. #endif
  127. #ifdef WOLFSSL_TIRTOS
  128. fdOpenSession(Task_self());
  129. #endif
  130. server_args.signal = &ready;
  131. InitTcpReady(&ready);
  132. #ifndef NO_CRYPT_TEST
  133. /* wc_ test */
  134. #ifdef HAVE_STACK_SIZE
  135. StackSizeCheck(&server_args, wolfcrypt_test);
  136. #else
  137. wolfcrypt_test(&server_args);
  138. #endif
  139. if (server_args.return_code != 0) return server_args.return_code;
  140. #endif
  141. /* Simple wolfSSL client server test */
  142. #ifdef HAVE_STACK_SIZE
  143. StackSizeCheck(&server_args, (THREAD_RETURN (*)(void *))simple_test);
  144. #else
  145. simple_test(&server_args);
  146. #endif
  147. if (server_args.return_code != 0) return server_args.return_code;
  148. #if !defined(NETOS)
  149. /* Echo input wolfSSL client server test */
  150. #ifdef HAVE_STACK_SIZE
  151. StackSizeCheck_launch(&server_args, echoserver_test, &serverThread,
  152. &serverThreadStackContext);
  153. #else
  154. start_thread(echoserver_test, &server_args, &serverThread);
  155. #endif
  156. /* Create unique file name */
  157. outputName = mymktemp(tempName, tempName_len, tempName_Xnum);
  158. if (outputName == NULL) {
  159. printf("Could not create unique file name");
  160. return EXIT_FAILURE;
  161. }
  162. ret = test_tls(&server_args);
  163. if (ret != 0) {
  164. cleanup_output();
  165. return ret;
  166. }
  167. /* Server won't quit unless TLS test has worked. */
  168. #ifdef HAVE_STACK_SIZE
  169. fputs("reaping echoserver_test: ", stdout);
  170. StackSizeCheck_reap(serverThread, serverThreadStackContext);
  171. #else
  172. join_thread(serverThread);
  173. #endif
  174. if (server_args.return_code != 0) {
  175. cleanup_output();
  176. return server_args.return_code;
  177. }
  178. #endif /* !NETOS */
  179. show_ciphers();
  180. #if !defined(NETOS)
  181. ret = validate_cleanup_output();
  182. if (ret != 0)
  183. return EXIT_FAILURE;
  184. #endif
  185. wolfSSL_Cleanup();
  186. FreeTcpReady(&ready);
  187. #ifdef WOLFSSL_TIRTOS
  188. fdCloseSession(Task_self());
  189. #endif
  190. #ifdef HAVE_WNR
  191. if (wc_FreeNetRandom() < 0)
  192. err_sys("Failed to free netRandom context");
  193. #endif /* HAVE_WNR */
  194. printf("\nAll tests passed!\n");
  195. #else
  196. (void)argc;
  197. (void)argv;
  198. #endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */
  199. return EXIT_SUCCESS;
  200. }
  201. #if !defined(NO_WOLFSSL_SERVER) && !defined(NO_WOLFSSL_CLIENT) && \
  202. (!defined(WOLF_CRYPTO_CB_ONLY_RSA) && !defined(WOLF_CRYPTO_CB_ONLY_ECC))
  203. /* Perform a basic TLS handshake.
  204. *
  205. * First connection to echo a file.
  206. * Second to tell TLS server to quit.
  207. *
  208. * @param [in,out] server_args Object sent to server thread.
  209. * @return 0 on success.
  210. * @return echoclient error return code on failure.
  211. */
  212. static int test_tls(func_args* server_args)
  213. {
  214. func_args echo_args;
  215. char* myArgv[NUMARGS];
  216. char arg[3][128];
  217. /* Set up command line arguments for echoclient to send input file
  218. * and write echoed data to temporary output file. */
  219. myArgv[0] = arg[0];
  220. myArgv[1] = arg[1];
  221. myArgv[2] = arg[2];
  222. echo_args.argc = 3;
  223. echo_args.argv = myArgv;
  224. XSTRLCPY(arg[0], "testsuite", sizeof(arg[0]));
  225. XSTRLCPY(arg[1], "input", sizeof(arg[1]));
  226. XSTRLCPY(arg[2], outputName, sizeof(arg[2]));
  227. /* Share the signal, it has the new port number in it. */
  228. echo_args.signal = server_args->signal;
  229. /* Ready to execute client - wait for server to be ready. */
  230. wait_tcp_ready(server_args);
  231. /* Do a client TLS connection. */
  232. #ifdef HAVE_STACK_SIZE
  233. fputs("echoclient_test #1: ", stdout);
  234. StackSizeCheck(&echo_args, echoclient_test_wrapper);
  235. #else
  236. echoclient_test(&echo_args);
  237. #endif
  238. if (echo_args.return_code != 0)
  239. return echo_args.return_code;
  240. #ifdef WOLFSSL_DTLS
  241. /* Ensure server is ready for UDP data. */
  242. wait_tcp_ready(server_args);
  243. #endif
  244. /* Next client connection - send quit to shutdown server. */
  245. echo_args.argc = 2;
  246. XSTRLCPY(arg[1], "quit", sizeof(arg[1]));
  247. /* Do a client TLS connection. */
  248. #ifdef HAVE_STACK_SIZE
  249. fputs("echoclient_test #2: ", stdout);
  250. StackSizeCheck(&echo_args, echoclient_test_wrapper);
  251. #else
  252. echoclient_test(&echo_args);
  253. #endif
  254. if (echo_args.return_code != 0)
  255. return echo_args.return_code;
  256. return 0;
  257. }
  258. /* Show cipher suites available. */
  259. static void show_ciphers(void)
  260. {
  261. char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
  262. XMEMSET(ciphers, 0, sizeof(ciphers));
  263. wolfSSL_get_ciphers(ciphers, sizeof(ciphers)-1);
  264. printf("ciphers = %s\n", ciphers);
  265. }
  266. /* Cleanup temporary output file. */
  267. static void cleanup_output(void)
  268. {
  269. remove(outputName);
  270. }
  271. /* Validate output equals input using a hash. Remove temporary output file.
  272. *
  273. * @return 0 on success.
  274. * @return 1 on failure.
  275. */
  276. static int validate_cleanup_output(void)
  277. {
  278. #ifndef NO_SHA256
  279. byte input[WC_SHA256_DIGEST_SIZE];
  280. byte output[WC_SHA256_DIGEST_SIZE];
  281. file_test("input", input);
  282. file_test(outputName, output);
  283. #endif
  284. cleanup_output();
  285. #ifndef NO_SHA256
  286. if (memcmp(input, output, sizeof(input)) != 0)
  287. return 1;
  288. #endif
  289. return 0;
  290. }
  291. /* Simple server.
  292. *
  293. * @param [in] args Object for server data in thread.
  294. * @return Return code.
  295. */
  296. #ifdef HAVE_STACK_SIZE
  297. static THREAD_RETURN simple_test(func_args* args)
  298. #else
  299. static void simple_test(func_args* args)
  300. #endif
  301. {
  302. THREAD_TYPE serverThread;
  303. int i;
  304. func_args svrArgs;
  305. char *svrArgv[9];
  306. char argvs[9][32];
  307. func_args cliArgs;
  308. char *cliArgv[NUMARGS];
  309. char argvc[3][32];
  310. for (i = 0; i < 9; i++)
  311. svrArgv[i] = argvs[i];
  312. for (i = 0; i < 3; i++)
  313. cliArgv[i] = argvc[i];
  314. XSTRLCPY(argvs[0], "SimpleServer", sizeof(argvs[0]));
  315. svrArgs.argc = 1;
  316. svrArgs.argv = svrArgv;
  317. svrArgs.return_code = 0;
  318. #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_SNIFFER) && \
  319. !defined(WOLFSSL_TIRTOS)
  320. XSTRLCPY(argvs[svrArgs.argc++], "-p", sizeof(argvs[svrArgs.argc]));
  321. XSTRLCPY(argvs[svrArgs.argc++], "0", sizeof(argvs[svrArgs.argc]));
  322. #endif
  323. /* Set the last arg later, when it is known. */
  324. args->return_code = 0;
  325. svrArgs.signal = args->signal;
  326. start_thread(server_test, &svrArgs, &serverThread);
  327. wait_tcp_ready(&svrArgs);
  328. /* Setting the actual port number. */
  329. XSTRLCPY(argvc[0], "SimpleClient", sizeof(argvc[0]));
  330. cliArgs.argv = cliArgv;
  331. cliArgs.return_code = 0;
  332. #ifndef USE_WINDOWS_API
  333. cliArgs.argc = NUMARGS;
  334. XSTRLCPY(argvc[1], "-p", sizeof(argvc[1]));
  335. (void)snprintf(argvc[2], sizeof(argvc[2]), "%d", (int)svrArgs.signal->port);
  336. #else
  337. cliArgs.argc = 1;
  338. #endif
  339. client_test(&cliArgs);
  340. if (cliArgs.return_code != 0) {
  341. args->return_code = cliArgs.return_code;
  342. #ifdef HAVE_STACK_SIZE
  343. return (THREAD_RETURN)0;
  344. #else
  345. return;
  346. #endif
  347. }
  348. join_thread(serverThread);
  349. if (svrArgs.return_code != 0) args->return_code = svrArgs.return_code;
  350. #ifdef HAVE_STACK_SIZE
  351. return (THREAD_RETURN)0;
  352. #endif
  353. }
  354. #endif /* !NO_WOLFSSL_SERVER && !NO_WOLFSSL_CLIENT */
  355. /* Wait for the server to be ready for a connection.
  356. *
  357. * @param [in] args Object to send to thread.
  358. */
  359. void wait_tcp_ready(func_args* args)
  360. {
  361. #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
  362. PTHREAD_CHECK_RET(pthread_mutex_lock(&args->signal->mutex));
  363. if (!args->signal->ready)
  364. PTHREAD_CHECK_RET(pthread_cond_wait(&args->signal->cond,
  365. &args->signal->mutex));
  366. args->signal->ready = 0; /* reset */
  367. PTHREAD_CHECK_RET(pthread_mutex_unlock(&args->signal->mutex));
  368. #elif defined(NETOS)
  369. (void)tx_mutex_get(&args->signal->mutex, TX_WAIT_FOREVER);
  370. /* TODO:
  371. * if (!args->signal->ready)
  372. * pthread_cond_wait(&args->signal->cond, &args->signal->mutex);
  373. * args->signal->ready = 0; */
  374. (void)tx_mutex_put(&args->signal->mutex);
  375. #elif defined(USE_WINDOWS_API)
  376. /* Give peer a moment to get running */
  377. _sleep(500);
  378. #else
  379. (void)args;
  380. #endif
  381. }
  382. /* Start a thread.
  383. *
  384. * @param [in] fun Function to executre in thread.
  385. * @param [in] args Object to send to function in thread.
  386. * @param [out] thread Handle to thread.
  387. */
  388. void start_thread(THREAD_FUNC fun, func_args* args, THREAD_TYPE* thread)
  389. {
  390. #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
  391. PTHREAD_CHECK_RET(pthread_create(thread, 0, fun, args));
  392. return;
  393. #elif defined(WOLFSSL_TIRTOS)
  394. /* Initialize the defaults and set the parameters. */
  395. Task_Params taskParams;
  396. Task_Params_init(&taskParams);
  397. taskParams.arg0 = (UArg)args;
  398. taskParams.stackSize = 65535;
  399. *thread = Task_create((Task_FuncPtr)fun, &taskParams, NULL);
  400. if (*thread == NULL) {
  401. printf("Failed to create new Task\n");
  402. }
  403. Task_yield();
  404. #elif defined(NETOS)
  405. /* This can be adjusted by defining in user_settings.h, will default to 65k
  406. * in the event it is undefined */
  407. #ifndef TESTSUITE_THREAD_STACK_SZ
  408. #define TESTSUITE_THREAD_STACK_SZ 65535
  409. #endif
  410. int result;
  411. static void * TestSuiteThreadStack = NULL;
  412. /* Assume only one additional thread is created concurrently. */
  413. if (TestSuiteThreadStack == NULL)
  414. {
  415. TestSuiteThreadStack = (void *)malloc(TESTSUITE_THREAD_STACK_SZ);
  416. if (TestSuiteThreadStack == NULL)
  417. {
  418. printf ("Stack allocation failure.\n");
  419. return;
  420. }
  421. }
  422. memset (thread, 0, sizeof *thread);
  423. /* first create the idle thread:
  424. * ARGS:
  425. * Param1: pointer to thread
  426. * Param2: name
  427. * Param3 and 4: entry function and input
  428. * Param5: pointer to thread stack
  429. * Param6: stack size
  430. * Param7 and 8: priority level and preempt threshold
  431. * Param9 and 10: time slice and auto-start indicator */
  432. result = tx_thread_create(thread,
  433. "WolfSSL TestSuiteThread",
  434. (entry_functionType)fun, (ULONG)args,
  435. TestSuiteThreadStack,
  436. TESTSUITE_THREAD_STACK_SZ,
  437. 2, 2,
  438. 1, TX_AUTO_START);
  439. if (result != TX_SUCCESS)
  440. {
  441. printf("Ethernet Bypass Application: failed to create idle thread!\n");
  442. }
  443. #else
  444. *thread = (THREAD_TYPE)_beginthreadex(0, 0, fun, args, 0, 0);
  445. #endif
  446. }
  447. /* Join thread to wait for completion.
  448. *
  449. * @param [in] thread Handle to thread.
  450. */
  451. void join_thread(THREAD_TYPE thread)
  452. {
  453. #if defined(_POSIX_THREADS) && !defined(__MINGW32__)
  454. PTHREAD_CHECK_RET(pthread_join(thread, 0));
  455. #elif defined(WOLFSSL_TIRTOS)
  456. while(1) {
  457. if (Task_getMode(thread) == Task_Mode_TERMINATED) {
  458. Task_sleep(5);
  459. break;
  460. }
  461. Task_yield();
  462. }
  463. #elif defined(NETOS)
  464. /* TODO: */
  465. #else
  466. int res = WaitForSingleObject((HANDLE)thread, INFINITE);
  467. assert(res == WAIT_OBJECT_0);
  468. res = CloseHandle((HANDLE)thread);
  469. assert(res);
  470. (void)res; /* Suppress un-used variable warning */
  471. #endif
  472. }
  473. #ifndef NO_SHA256
  474. /* Create SHA-256 hash of the file based on filename.
  475. *
  476. * @param [in] file Name of file.
  477. * @parma [out] check Buffer to hold SHA-256 hash.
  478. */
  479. void file_test(const char* file, byte* check)
  480. {
  481. FILE* f;
  482. int i = 0, j, ret;
  483. wc_Sha256 sha256;
  484. byte buf[1024];
  485. byte shasum[WC_SHA256_DIGEST_SIZE];
  486. ret = wc_InitSha256(&sha256);
  487. if (ret != 0) {
  488. printf("Can't wc_InitSha256 %d\n", ret);
  489. return;
  490. }
  491. if( !( f = fopen( file, "rb" ) )) {
  492. printf("Can't open %s\n", file);
  493. return;
  494. }
  495. while( ( i = (int)fread(buf, 1, sizeof(buf), f )) > 0 ) {
  496. ret = wc_Sha256Update(&sha256, buf, i);
  497. if (ret != 0) {
  498. printf("Can't wc_Sha256Update %d\n", ret);
  499. fclose(f);
  500. return;
  501. }
  502. }
  503. ret = wc_Sha256Final(&sha256, shasum);
  504. wc_Sha256Free(&sha256);
  505. if (ret != 0) {
  506. printf("Can't wc_Sha256Final %d\n", ret);
  507. fclose(f);
  508. return;
  509. }
  510. XMEMCPY(check, shasum, sizeof(shasum));
  511. for(j = 0; j < WC_SHA256_DIGEST_SIZE; ++j )
  512. printf( "%02x", shasum[j] );
  513. printf(" %s\n", file);
  514. fclose(f);
  515. }
  516. #endif
  517. #else /* SINGLE_THREADED */
  518. int myoptind = 0;
  519. char* myoptarg = NULL;
  520. int main(int argc, char** argv)
  521. {
  522. func_args wolfcrypt_test_args;
  523. wolfcrypt_test_args.argc = argc;
  524. wolfcrypt_test_args.argv = argv;
  525. wolfSSL_Init();
  526. ChangeToWolfRoot();
  527. /* No TLS - only doing cryptographic algorithm testing. */
  528. wolfcrypt_test(&wolfcrypt_test_args);
  529. if (wolfcrypt_test_args.return_code != 0)
  530. return wolfcrypt_test_args.return_code;
  531. wolfSSL_Cleanup();
  532. printf("\nAll tests passed!\n");
  533. return EXIT_SUCCESS;
  534. }
  535. #endif /* SINGLE_THREADED */