tls_sock.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /* tls_sock.c
  2. *
  3. * Copyright (C) 2006-2023 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. #include <wolfssl/options.h>
  22. #include <wolfssl/ssl.h>
  23. #define USE_CERT_BUFFERS_2048
  24. #include <wolfssl/certs_test.h>
  25. #include <wolfssl/test.h>
  26. #ifdef WOLFSSL_ZEPHYR
  27. #define printf printk
  28. #endif
  29. #define BUFFER_SIZE 2048
  30. #define STATIC_MEM_SIZE (96*1024)
  31. #define THREAD_STACK_SIZE (12*1024)
  32. #define MAX_SEND_SIZE 256
  33. /* The stack to use in the server's thread. */
  34. K_THREAD_STACK_DEFINE(server_stack, THREAD_STACK_SIZE);
  35. #ifdef WOLFSSL_STATIC_MEMORY
  36. static WOLFSSL_HEAP_HINT* HEAP_HINT_SERVER;
  37. static WOLFSSL_HEAP_HINT* HEAP_HINT_CLIENT;
  38. static byte gMemoryServer[STATIC_MEM_SIZE];
  39. static byte gMemoryClient[STATIC_MEM_SIZE];
  40. #else
  41. #define HEAP_HINT_SERVER NULL
  42. #define HEAP_HINT_CLIENT NULL
  43. #endif /* WOLFSSL_STATIC_MEMORY */
  44. /* Application data to send. */
  45. static const char msgHTTPGet[] = "GET /index.html HTTP/1.0\r\n\r\n";
  46. static const char msgHTTPIndex[] =
  47. "HTTP/1.1 200 OK\n"
  48. "Content-Type: text/html\n"
  49. "Connection: close\n"
  50. "\n"
  51. "<html>\n"
  52. "<head>\n"
  53. "<title>Welcome to wolfSSL!</title>\n"
  54. "</head>\n"
  55. "<body>\n"
  56. "<p>wolfSSL has successfully performed handshake!</p>\n"
  57. "</body>\n"
  58. "</html>\n";
  59. /* Create a new wolfSSL client with a server CA certificate. */
  60. static int wolfssl_client_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
  61. {
  62. int ret = 0;
  63. WOLFSSL_CTX* client_ctx = NULL;
  64. WOLFSSL* client_ssl = NULL;
  65. /* Create and initialize WOLFSSL_CTX */
  66. if ((client_ctx = wolfSSL_CTX_new_ex(wolfTLSv1_2_client_method(),
  67. HEAP_HINT_CLIENT)) == NULL) {
  68. printf("ERROR: failed to create WOLFSSL_CTX\n");
  69. ret = -1;
  70. }
  71. if (ret == 0) {
  72. /* Load client certificates into WOLFSSL_CTX */
  73. if (wolfSSL_CTX_load_verify_buffer(client_ctx, ca_cert_der_2048,
  74. sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1) !=
  75. WOLFSSL_SUCCESS) {
  76. printf("ERROR: failed to load CA certificate\n");
  77. ret = -1;
  78. }
  79. }
  80. if (ret == 0) {
  81. /* Create a WOLFSSL object */
  82. if ((client_ssl = wolfSSL_new(client_ctx)) == NULL) {
  83. printf("ERROR: failed to create WOLFSSL object\n");
  84. ret = -1;
  85. }
  86. }
  87. if (ret == 0) {
  88. /* Return newly created wolfSSL context and object */
  89. *ctx = client_ctx;
  90. *ssl = client_ssl;
  91. }
  92. else {
  93. if (client_ssl != NULL)
  94. wolfSSL_free(client_ssl);
  95. if (client_ctx != NULL)
  96. wolfSSL_CTX_free(client_ctx);
  97. }
  98. return ret;
  99. }
  100. /* Client connecting to server using TLS */
  101. static int wolfssl_client_connect(WOLFSSL* ssl)
  102. {
  103. int ret = 0;
  104. if (wolfSSL_connect(ssl) != WOLFSSL_SUCCESS) {
  105. printf("wolfSSL Error: %d\n", wolfSSL_get_error(ssl, -1));
  106. if (!wolfSSL_want_read(ssl) && !wolfSSL_want_write(ssl))
  107. ret = -1;
  108. }
  109. return ret;
  110. }
  111. /* Create a new wolfSSL server with a certificate for authentication. */
  112. static int wolfssl_server_new(WOLFSSL_CTX** ctx, WOLFSSL** ssl)
  113. {
  114. int ret = 0;
  115. WOLFSSL_CTX* server_ctx = NULL;
  116. WOLFSSL* server_ssl = NULL;
  117. /* Create and initialize WOLFSSL_CTX */
  118. if ((server_ctx = wolfSSL_CTX_new_ex(wolfTLSv1_2_server_method(),
  119. HEAP_HINT_SERVER)) == NULL) {
  120. printf("ERROR: failed to create WOLFSSL_CTX\n");
  121. ret = -1;
  122. }
  123. if (ret == 0) {
  124. /* Load client certificates into WOLFSSL_CTX */
  125. if (wolfSSL_CTX_use_certificate_buffer(server_ctx,
  126. server_cert_der_2048, sizeof_server_cert_der_2048,
  127. WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  128. printf("ERROR: failed to load server certificate\n");
  129. ret = -1;
  130. }
  131. }
  132. if (ret == 0) {
  133. /* Load client certificates into WOLFSSL_CTX */
  134. if (wolfSSL_CTX_use_PrivateKey_buffer(server_ctx,
  135. server_key_der_2048, sizeof_server_key_der_2048,
  136. WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  137. printf("ERROR: failed to load server key\n");
  138. ret = -1;
  139. }
  140. }
  141. if (ret == 0) {
  142. /* Create a WOLFSSL object */
  143. if ((server_ssl = wolfSSL_new(server_ctx)) == NULL) {
  144. printf("ERROR: failed to create WOLFSSL object\n");
  145. ret = -1;
  146. }
  147. }
  148. if (ret == 0) {
  149. /* Return newly created wolfSSL context and object */
  150. *ctx = server_ctx;
  151. *ssl = server_ssl;
  152. }
  153. else {
  154. if (server_ssl != NULL)
  155. wolfSSL_free(server_ssl);
  156. if (server_ctx != NULL)
  157. wolfSSL_CTX_free(server_ctx);
  158. }
  159. return ret;
  160. }
  161. /* Server accepting a client using TLS */
  162. static int wolfssl_server_accept(WOLFSSL* ssl)
  163. {
  164. int ret = 0;
  165. if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) {
  166. printf("wolfSSL Error: %d\n", wolfSSL_get_error(ssl, -1));
  167. if (!wolfSSL_want_read(ssl) && !wolfSSL_want_write(ssl))
  168. ret = -1;
  169. }
  170. return ret;
  171. }
  172. /* Send application data. */
  173. static int wolfssl_send(WOLFSSL* ssl, const char* msg)
  174. {
  175. int ret = 0;
  176. int len;
  177. printf("Sending:\n%s\n", msg);
  178. len = wolfSSL_write(ssl, msg, XSTRLEN(msg));
  179. if (len < 0)
  180. ret = len;
  181. else if (len != XSTRLEN(msg))
  182. ret = -1;
  183. return ret;
  184. }
  185. /* Receive application data. */
  186. static int wolfssl_recv(WOLFSSL* ssl)
  187. {
  188. int ret;
  189. byte reply[256];
  190. ret = wolfSSL_read(ssl, reply, sizeof(reply)-1);
  191. if (ret > 0) {
  192. reply[ret] = '\0';
  193. printf("Received:\n%s\n", reply);
  194. ret = 1;
  195. }
  196. else if (wolfSSL_want_read(ssl) || wolfSSL_want_write(ssl))
  197. ret = 0;
  198. return ret;
  199. }
  200. /* Free the WOLFSSL object and context. */
  201. static void wolfssl_free(WOLFSSL_CTX* ctx, WOLFSSL* ssl)
  202. {
  203. if (ssl != NULL)
  204. wolfSSL_free(ssl);
  205. if (ctx != NULL)
  206. wolfSSL_CTX_free(ctx);
  207. }
  208. /* Display the static memory usage. */
  209. static void wolfssl_memstats(WOLFSSL* ssl)
  210. {
  211. #ifdef WOLFSSL_STATIC_MEMORY
  212. WOLFSSL_MEM_CONN_STATS ssl_stats;
  213. XMEMSET(&ssl_stats, 0 , sizeof(ssl_stats));
  214. if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1)
  215. printf("static memory was not used with ssl");
  216. else {
  217. printf("*** This is memory state before wolfSSL_free is called\n");
  218. printf("peak connection memory = %d\n", ssl_stats.peakMem);
  219. printf("current memory in use = %d\n", ssl_stats.curMem);
  220. printf("peak connection allocs = %d\n", ssl_stats.peakAlloc);
  221. printf("current connection allocs = %d\n",ssl_stats.curAlloc);
  222. printf("total connection allocs = %d\n",ssl_stats.totalAlloc);
  223. printf("total connection frees = %d\n\n", ssl_stats.totalFr);
  224. }
  225. #else
  226. (void)ssl;
  227. #endif
  228. }
  229. /* Start the server thread. */
  230. void start_thread(THREAD_FUNC func, func_args* args, THREAD_TYPE* thread)
  231. {
  232. k_thread_create(thread, server_stack, K_THREAD_STACK_SIZEOF(server_stack),
  233. func, args, NULL, NULL, 5, 0, K_NO_WAIT);
  234. }
  235. void join_thread(THREAD_TYPE thread)
  236. {
  237. /* Threads are handled in the kernel. */
  238. }
  239. int wolfssl_server_accept_tcp(WOLFSSL* ssl, SOCKET_T* fd, SOCKET_T* acceptfd)
  240. {
  241. int ret = 0;
  242. SOCKET_T sockfd;
  243. SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
  244. SOCKADDR_IN_T client;
  245. socklen_t client_len = sizeof(client);
  246. word16 port = 443;
  247. struct sockaddr_in bind_addr;
  248. sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  249. bind_addr.sin_family = AF_INET;
  250. bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  251. bind_addr.sin_port = htons(port);
  252. if (bind(sockfd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0)
  253. ret = -1;
  254. if (ret == 0) {
  255. *fd = sockfd;
  256. printf("Server Listen\n");
  257. listen(sockfd, 5);
  258. if (WOLFSSL_SOCKET_IS_INVALID(sockfd))
  259. ret = -1;
  260. }
  261. if (ret == 0) {
  262. printf("Server Accept\n");
  263. clientfd = accept(sockfd, (struct sockaddr*)&client,
  264. (ACCEPT_THIRD_T)&client_len);
  265. if (WOLFSSL_SOCKET_IS_INVALID(clientfd))
  266. ret = -1;
  267. }
  268. if (ret == 0) {
  269. *acceptfd = clientfd;
  270. tcp_set_nonblocking(&clientfd);
  271. printf("Server has client\n");
  272. if (wolfSSL_set_fd(ssl, clientfd) != WOLFSSL_SUCCESS)
  273. ret = -1;
  274. }
  275. return ret;
  276. }
  277. /* Thread to do the server operations. */
  278. void server_thread(void* arg1, void* arg2, void* arg3)
  279. {
  280. int ret = 0;
  281. WOLFSSL_CTX* server_ctx = NULL;
  282. WOLFSSL* server_ssl = NULL;
  283. SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
  284. SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;
  285. #ifdef WOLFSSL_STATIC_MEMORY
  286. if (wc_LoadStaticMemory(&HEAP_HINT_SERVER, gMemoryServer,
  287. sizeof(gMemoryServer),
  288. WOLFMEM_GENERAL | WOLFMEM_TRACK_STATS, 1) != 0) {
  289. printf("unable to load static memory");
  290. ret = -1;
  291. }
  292. if (ret == 0)
  293. #endif
  294. ret = wolfssl_server_new(&server_ctx, &server_ssl);
  295. if (ret == 0)
  296. ret = wolfssl_server_accept_tcp(server_ssl, &sockfd, &clientfd);
  297. while (ret == 0) {
  298. k_sleep(Z_TIMEOUT_TICKS(100));
  299. ret = wolfssl_server_accept(server_ssl);
  300. if (ret == 0 && wolfSSL_is_init_finished(server_ssl))
  301. break;
  302. }
  303. /* Receive HTTP request */
  304. while (ret == 0) {
  305. ret = wolfssl_recv(server_ssl);
  306. }
  307. if (ret == 1)
  308. ret = 0;
  309. /* Send HTTP response */
  310. if (ret == 0)
  311. ret = wolfssl_send(server_ssl, msgHTTPIndex);
  312. printf("Server Return: %d\n", ret);
  313. #ifdef WOLFSSL_STATIC_MEMORY
  314. printf("Server Memory Stats\n");
  315. #endif
  316. wolfssl_memstats(server_ssl);
  317. wolfssl_free(server_ctx, server_ssl);
  318. if (clientfd != WOLFSSL_SOCKET_INVALID)
  319. CloseSocket(clientfd);
  320. if (sockfd != WOLFSSL_SOCKET_INVALID)
  321. CloseSocket(sockfd);
  322. }
  323. int wolfssl_client_connect_tcp(WOLFSSL* ssl, SOCKET_T* fd)
  324. {
  325. int ret = 0;
  326. SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
  327. static struct addrinfo hints;
  328. struct addrinfo* res;
  329. XMEMSET(&hints, 0, sizeof(hints));
  330. hints.ai_family = AF_INET;
  331. hints.ai_socktype = SOCK_STREAM;
  332. if (getaddrinfo("192.0.2.1", "443", &hints, &res) != 0)
  333. ret = -1;
  334. if (ret == 0) {
  335. printf("Client socket\n");
  336. sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  337. if (WOLFSSL_SOCKET_IS_INVALID(sockfd))
  338. ret = -1;
  339. }
  340. if (ret == 0) {
  341. *fd = sockfd;
  342. tcp_set_nonblocking(&sockfd);
  343. printf("Client Connect\n");
  344. if (connect(sockfd, res->ai_addr, res->ai_addrlen) != 0)
  345. ret = -1;
  346. }
  347. if (ret == 0) {
  348. printf("Client Connected\n");
  349. if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS)
  350. ret = -1;
  351. }
  352. return ret;
  353. }
  354. /* Thread to do the client operations. */
  355. void client_thread()
  356. {
  357. int ret = 0;
  358. WOLFSSL_CTX* client_ctx = NULL;
  359. WOLFSSL* client_ssl = NULL;
  360. SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;
  361. #ifdef WOLFSSL_STATIC_MEMORY
  362. if (wc_LoadStaticMemory(&HEAP_HINT_CLIENT, gMemoryClient,
  363. sizeof(gMemoryClient),
  364. WOLFMEM_GENERAL | WOLFMEM_TRACK_STATS, 1) != 0) {
  365. printf("unable to load static memory");
  366. ret = -1;
  367. }
  368. if (ret == 0)
  369. #endif
  370. {
  371. /* Client connection */
  372. ret = wolfssl_client_new(&client_ctx, &client_ssl);
  373. }
  374. if (ret == 0)
  375. ret = wolfssl_client_connect_tcp(client_ssl, &sockfd);
  376. while (ret == 0) {
  377. k_sleep(Z_TIMEOUT_TICKS(10));
  378. ret = wolfssl_client_connect(client_ssl);
  379. if (ret == 0 && wolfSSL_is_init_finished(client_ssl))
  380. break;
  381. }
  382. if (ret == 0) {
  383. printf("Handshake complete\n");
  384. /* Send HTTP request */
  385. ret = wolfssl_send(client_ssl, msgHTTPGet);
  386. }
  387. /* Receive HTTP response */
  388. while (ret == 0) {
  389. k_sleep(Z_TIMEOUT_TICKS(10));
  390. ret = wolfssl_recv(client_ssl);
  391. }
  392. if (ret == 1)
  393. ret = 0;
  394. printf("Client Return: %d\n", ret);
  395. #ifdef WOLFSSL_STATIC_MEMORY
  396. printf("Client Memory Stats\n");
  397. #endif
  398. wolfssl_memstats(client_ssl);
  399. wolfssl_free(client_ctx, client_ssl);
  400. if (sockfd != WOLFSSL_SOCKET_INVALID)
  401. CloseSocket(sockfd);
  402. }
  403. int main()
  404. {
  405. THREAD_TYPE serverThread;
  406. wolfSSL_Init();
  407. #ifdef DEBUG_WOLFSSL
  408. wolfSSL_Debugging_ON();
  409. #endif
  410. /* Start server */
  411. start_thread(server_thread, NULL, &serverThread);
  412. k_sleep(Z_TIMEOUT_TICKS(100));
  413. client_thread();
  414. join_thread(serverThread);
  415. wolfSSL_Cleanup();
  416. printf("Done\n");
  417. return 0;
  418. }