testsuite.c 15 KB

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