1
0

echoclient.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /* echoclient.c
  2. *
  3. * Copyright (C) 2006-2024 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. #ifndef WOLFSSL_USER_SETTINGS
  26. #include <wolfssl/options.h>
  27. #endif
  28. /* Force enable the compatibility macros for this example */
  29. #undef TEST_OPENSSL_COEXIST
  30. #undef OPENSSL_COEXIST
  31. #ifndef OPENSSL_EXTRA_X509_SMALL
  32. #define OPENSSL_EXTRA_X509_SMALL
  33. #endif
  34. #include <wolfssl/ssl.h>
  35. #ifdef WOLFSSL_DTLS
  36. #include <wolfssl/error-ssl.h>
  37. #endif
  38. #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET)
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include "cmsis_os.h"
  42. #include "rl_fs.h"
  43. #include "rl_net.h"
  44. #include "wolfssl_MDK_ARM.h"
  45. #endif
  46. #include <wolfssl/test.h>
  47. #include <wolfssl/openssl/ssl.h>
  48. #include <examples/echoclient/echoclient.h>
  49. #ifndef NO_WOLFSSL_CLIENT
  50. #ifdef NO_FILESYSTEM
  51. #ifdef NO_RSA
  52. #error currently the example only tries to load in a RSA buffer
  53. #endif
  54. #undef USE_CERT_BUFFERS_2048
  55. #define USE_CERT_BUFFERS_2048
  56. #include <wolfssl/certs_test.h>
  57. #endif
  58. #ifdef WOLFSSL_ASYNC_CRYPT
  59. static int devId = INVALID_DEVID;
  60. #endif
  61. void echoclient_test(void* args)
  62. {
  63. SOCKET_T sockfd = 0;
  64. FILE* fin = stdin ;
  65. FILE* fout = stdout;
  66. #ifndef WOLFSSL_MDK_SHELL
  67. int inCreated = 0;
  68. int outCreated = 0;
  69. #endif
  70. char msg[1024];
  71. char reply[1024+1];
  72. SSL_METHOD* method = 0;
  73. SSL_CTX* ctx = 0;
  74. SSL* ssl = 0;
  75. int ret = 0, err = 0;
  76. int doDTLS = 0;
  77. int doPSK = 0;
  78. int sendSz;
  79. #ifndef WOLFSSL_MDK_SHELL
  80. int argc = 0;
  81. char** argv = 0;
  82. #endif
  83. word16 port;
  84. char buffer[WOLFSSL_MAX_ERROR_SZ];
  85. ((func_args*)args)->return_code = -1; /* error state */
  86. #ifndef WOLFSSL_MDK_SHELL
  87. argc = ((func_args*)args)->argc;
  88. argv = ((func_args*)args)->argv;
  89. if (argc >= 2) {
  90. fin = fopen(argv[1], "r");
  91. inCreated = 1;
  92. }
  93. if (argc >= 3) {
  94. fout = fopen(argv[2], "w");
  95. outCreated = 1;
  96. }
  97. #endif
  98. if (!fin) err_sys("can't open input file");
  99. if (!fout) err_sys("can't open output file");
  100. #ifdef WOLFSSL_DTLS
  101. doDTLS = 1;
  102. #endif
  103. #ifdef WOLFSSL_LEANPSK
  104. doPSK = 1;
  105. #endif
  106. #if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
  107. !defined(HAVE_ED448)
  108. doPSK = 1;
  109. #endif
  110. (void)doPSK;
  111. #if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_SHELL)
  112. port = ((func_args*)args)->signal->port;
  113. #else
  114. port = wolfSSLPort;
  115. #endif
  116. #if defined(WOLFSSL_DTLS)
  117. #ifdef WOLFSSL_DTLS13
  118. method = wolfDTLSv1_3_client_method();
  119. #elif !defined(WOLFSSL_NO_TLS12)
  120. method = DTLSv1_2_client_method();
  121. #endif
  122. #elif !defined(NO_TLS)
  123. #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_SNIFFER)
  124. method = wolfTLSv1_2_client_method();
  125. #else
  126. method = wolfSSLv23_client_method();
  127. #endif
  128. #elif defined(WOLFSSL_ALLOW_SSLV3)
  129. method = SSLv3_client_method();
  130. #else
  131. #error "no valid client method type"
  132. #endif
  133. ctx = SSL_CTX_new(method);
  134. #ifndef NO_FILESYSTEM
  135. #ifndef NO_RSA
  136. if (SSL_CTX_load_verify_locations(ctx, caCertFile, 0) != WOLFSSL_SUCCESS)
  137. err_sys("can't load ca file, Please run from wolfSSL home dir");
  138. #endif
  139. #ifdef HAVE_ECC
  140. if (SSL_CTX_load_verify_locations(ctx, caEccCertFile, 0) != WOLFSSL_SUCCESS)
  141. err_sys("can't load ca file, Please run from wolfSSL home dir");
  142. #elif defined(HAVE_ED25519)
  143. if (SSL_CTX_load_verify_locations(ctx, caEdCertFile, 0) != WOLFSSL_SUCCESS)
  144. err_sys("can't load ca file, Please run from wolfSSL home dir");
  145. #elif defined(HAVE_ED448)
  146. if (SSL_CTX_load_verify_locations(ctx, caEd448CertFile, 0) != WOLFSSL_SUCCESS)
  147. err_sys("can't load ca file, Please run from wolfSSL home dir");
  148. #endif
  149. #elif !defined(NO_CERTS)
  150. if (!doPSK)
  151. if (wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048,
  152. sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS)
  153. err_sys("can't load ca buffer");
  154. #endif
  155. #if defined(WOLFSSL_SNIFFER)
  156. /* Only set if not running testsuite */
  157. if (XSTRSTR(argv[0], "testsuite") == NULL) {
  158. /* don't use EDH, can't sniff tmp keys */
  159. SSL_CTX_set_cipher_list(ctx, "AES256-SHA");
  160. }
  161. #endif
  162. #ifndef NO_PSK
  163. if (doPSK) {
  164. const char *defaultCipherList;
  165. wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
  166. #ifdef HAVE_NULL_CIPHER
  167. defaultCipherList = "PSK-NULL-SHA256";
  168. #elif defined(HAVE_AESGCM) && !defined(NO_DH)
  169. #ifdef WOLFSSL_TLS13
  170. defaultCipherList = "TLS13-AES128-GCM-SHA256"
  171. #ifndef WOLFSSL_NO_TLS12
  172. ":DHE-PSK-AES128-GCM-SHA256"
  173. #endif
  174. ;
  175. #else
  176. defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
  177. #endif
  178. #elif defined(HAVE_AESGCM) && defined(WOLFSSL_TLS13)
  179. defaultCipherList = "TLS13-AES128-GCM-SHA256"
  180. #ifndef WOLFSSL_NO_TLS12
  181. ":DHE-PSK-AES128-GCM-SHA256"
  182. #endif
  183. ;
  184. #else
  185. defaultCipherList = "PSK-AES128-CBC-SHA256";
  186. #endif
  187. if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=WOLFSSL_SUCCESS)
  188. err_sys("client can't set cipher list 2");
  189. wolfSSL_CTX_set_psk_callback_ctx(ctx, (void*)defaultCipherList);
  190. }
  191. #endif
  192. #ifdef WOLFSSL_ENCRYPTED_KEYS
  193. SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
  194. #endif
  195. #if defined(WOLFSSL_MDK_ARM)
  196. wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
  197. #endif
  198. #ifdef WOLFSSL_ASYNC_CRYPT
  199. ret = wolfAsync_DevOpen(&devId);
  200. if (ret < 0) {
  201. fprintf(stderr, "Async device open failed\nRunning without async\n");
  202. }
  203. wolfSSL_CTX_SetDevId(ctx, devId);
  204. #endif /* WOLFSSL_ASYNC_CRYPT */
  205. ssl = SSL_new(ctx);
  206. tcp_connect(&sockfd, wolfSSLIP, port, doDTLS, 0, ssl);
  207. SSL_set_fd(ssl, sockfd);
  208. #if defined(USE_WINDOWS_API) && defined(WOLFSSL_DTLS) && defined(NO_MAIN_DRIVER)
  209. /* let echoserver bind first, TODO: add Windows signal like pthreads does */
  210. Sleep(100);
  211. #endif
  212. do {
  213. err = 0; /* Reset error */
  214. ret = SSL_connect(ssl);
  215. if (ret != WOLFSSL_SUCCESS) {
  216. err = SSL_get_error(ssl, 0);
  217. #ifdef WOLFSSL_ASYNC_CRYPT
  218. if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
  219. ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
  220. if (ret < 0) break;
  221. }
  222. #endif
  223. }
  224. } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
  225. if (ret != WOLFSSL_SUCCESS) {
  226. fprintf(stderr, "SSL_connect error %d, %s\n", err,
  227. ERR_error_string((unsigned long)err, buffer));
  228. err_sys("SSL_connect failed");
  229. }
  230. while (fgets(msg, sizeof(msg), fin) != 0) {
  231. sendSz = (int)XSTRLEN(msg);
  232. do {
  233. err = 0; /* reset error */
  234. ret = SSL_write(ssl, msg, sendSz);
  235. if (ret <= 0) {
  236. err = SSL_get_error(ssl, 0);
  237. #ifdef WOLFSSL_ASYNC_CRYPT
  238. if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
  239. ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
  240. if (ret < 0) break;
  241. }
  242. #endif
  243. }
  244. } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
  245. if (ret != sendSz) {
  246. fprintf(stderr, "SSL_write msg error %d, %s\n", err,
  247. ERR_error_string((unsigned long)err, buffer));
  248. err_sys("SSL_write failed");
  249. }
  250. if (strncmp(msg, "quit", 4) == 0) {
  251. LIBCALL_CHECK_RET(fputs("sending server shutdown command: quit!\n",
  252. fout));
  253. break;
  254. }
  255. if (strncmp(msg, "break", 5) == 0) {
  256. LIBCALL_CHECK_RET(fputs("sending server session close: break!\n",
  257. fout));
  258. break;
  259. }
  260. #ifndef WOLFSSL_MDK_SHELL
  261. while (sendSz)
  262. #endif
  263. {
  264. do {
  265. err = 0; /* reset error */
  266. ret = SSL_read(ssl, reply, sizeof(reply)-1);
  267. if (ret <= 0) {
  268. err = SSL_get_error(ssl, 0);
  269. #ifdef WOLFSSL_ASYNC_CRYPT
  270. if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
  271. ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
  272. if (ret < 0) break;
  273. }
  274. #endif
  275. }
  276. } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
  277. if (ret > 0) {
  278. reply[ret] = 0;
  279. LIBCALL_CHECK_RET(fputs(reply, fout));
  280. LIBCALL_CHECK_RET(fflush(fout));
  281. sendSz -= ret;
  282. }
  283. #ifdef WOLFSSL_DTLS
  284. else if (wolfSSL_dtls(ssl) &&
  285. err == WC_NO_ERR_TRACE(DECRYPT_ERROR))
  286. {
  287. /* This condition is OK. The packet should be dropped
  288. * silently when there is a decrypt or MAC error on
  289. * a DTLS record. */
  290. sendSz = 0;
  291. }
  292. #endif
  293. else {
  294. fprintf(stderr, "SSL_read msg error %d, %s\n", err,
  295. ERR_error_string((unsigned long)err, buffer));
  296. err_sys("SSL_read failed");
  297. }
  298. }
  299. }
  300. #ifdef WOLFSSL_DTLS
  301. strncpy(msg, "break", 6);
  302. sendSz = (int)strlen(msg);
  303. /* try to tell server done */
  304. do {
  305. err = 0; /* reset error */
  306. ret = SSL_write(ssl, msg, sendSz);
  307. if (ret <= 0) {
  308. err = SSL_get_error(ssl, 0);
  309. #ifdef WOLFSSL_ASYNC_CRYPT
  310. if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
  311. ret = wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW);
  312. if (ret < 0) break;
  313. }
  314. #endif
  315. }
  316. } while (err == WC_NO_ERR_TRACE(WC_PENDING_E));
  317. #else
  318. SSL_shutdown(ssl);
  319. #endif
  320. SSL_free(ssl);
  321. SSL_CTX_free(ctx);
  322. #ifdef WOLFSSL_ASYNC_CRYPT
  323. wolfAsync_DevClose(&devId);
  324. #endif
  325. LIBCALL_CHECK_RET(fflush(fout));
  326. #ifndef WOLFSSL_MDK_SHELL
  327. if (inCreated) fclose(fin);
  328. if (outCreated) fclose(fout);
  329. #endif
  330. CloseSocket(sockfd);
  331. ((func_args*)args)->return_code = 0;
  332. }
  333. #endif /* !NO_WOLFSSL_CLIENT */
  334. /* so overall tests can pull in test function */
  335. #ifndef NO_MAIN_DRIVER
  336. int main(int argc, char** argv)
  337. {
  338. func_args args;
  339. #ifdef HAVE_WNR
  340. if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0)
  341. err_sys("Whitewood netRandom global config failed");
  342. #endif
  343. StartTCP();
  344. args.argc = argc;
  345. args.argv = argv;
  346. args.return_code = 0;
  347. wolfSSL_Init();
  348. #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL)
  349. wolfSSL_Debugging_ON();
  350. #endif
  351. #ifndef WOLFSSL_TIRTOS
  352. ChangeToWolfRoot();
  353. #endif
  354. #ifndef NO_WOLFSSL_CLIENT
  355. echoclient_test(&args);
  356. #endif
  357. wolfSSL_Cleanup();
  358. #ifdef HAVE_WNR
  359. if (wc_FreeNetRandom() < 0)
  360. err_sys("Failed to free netRandom context");
  361. #endif /* HAVE_WNR */
  362. return args.return_code;
  363. }
  364. #endif /* NO_MAIN_DRIVER */