memory-tls.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /* memory-tls.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. /* IoT-safe client side demo
  22. - server uses software crypto and buffers
  23. - client uses IoT-Safe
  24. Client and server communicates in a cooperative
  25. scheduling mechanism within the same thread.
  26. Two buffers in memory are used for client<=>server communication.
  27. */
  28. #include <wolfssl/wolfcrypt/settings.h>
  29. #include <wolfssl/ssl.h>
  30. #include <wolfssl/error-ssl.h>
  31. #include <wolfssl/wolfcrypt/port/iotsafe/iotsafe.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include "ca-cert.c"
  35. /* The following define
  36. * activates mutual authentication */
  37. #define CLIENT_AUTH
  38. #define CLIENT_IOTSAFE
  39. #define CA_ECC
  40. static int client_state = 0;
  41. static int server_state = 0;
  42. static uint8_t cert_buffer[2048];
  43. static uint32_t cert_buffer_size;
  44. static WOLFSSL_CTX* srv_ctx = NULL;
  45. static WOLFSSL* srv_ssl = NULL;
  46. static WOLFSSL_CTX *cli_ctx = NULL;
  47. static WOLFSSL *cli_ssl = NULL;
  48. /* client messages to server in memory */
  49. #define TLS_BUFFERS_SZ (1024 * 8)
  50. static unsigned char to_server[TLS_BUFFERS_SZ];
  51. static int server_bytes;
  52. static int server_write_idx;
  53. static int server_read_idx;
  54. /* server messages to client in memory */
  55. static unsigned char to_client[TLS_BUFFERS_SZ];
  56. static int client_bytes;
  57. static int client_write_idx;
  58. static int client_read_idx;
  59. /* server send callback */
  60. int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  61. {
  62. if (client_write_idx + sz > TLS_BUFFERS_SZ) {
  63. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  64. }
  65. printf("=== Srv-Cli: %d\n", sz);
  66. XMEMCPY(&to_client[client_write_idx], buf, sz);
  67. client_write_idx += sz;
  68. client_bytes += sz;
  69. return sz;
  70. }
  71. /* server recv callback */
  72. int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  73. {
  74. if (server_bytes - server_read_idx < sz) {
  75. return WOLFSSL_CBIO_ERR_WANT_READ;
  76. }
  77. XMEMCPY(buf, &to_server[server_read_idx], sz);
  78. server_read_idx += sz;
  79. if (server_read_idx == server_write_idx) {
  80. server_read_idx = server_write_idx = 0;
  81. server_bytes = 0;
  82. }
  83. printf("=== Srv RX: %d\n", sz);
  84. return sz;
  85. }
  86. /* client send callback */
  87. int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  88. {
  89. if (server_write_idx + sz > TLS_BUFFERS_SZ)
  90. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  91. printf("=== Cli->Srv: %d\n", sz);
  92. XMEMCPY(&to_server[server_write_idx], buf, sz);
  93. server_write_idx += sz;
  94. server_bytes += sz;
  95. return sz;
  96. }
  97. /* client recv callback */
  98. int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  99. {
  100. if (client_bytes - client_read_idx < sz) {
  101. return WOLFSSL_CBIO_ERR_WANT_READ;
  102. }
  103. XMEMCPY(buf, &to_client[client_read_idx], sz);
  104. client_read_idx += sz;
  105. if (client_read_idx == client_write_idx) {
  106. client_read_idx = client_write_idx = 0;
  107. client_bytes = 0;
  108. }
  109. printf("=== Cli RX: %d\n", sz);
  110. return sz;
  111. }
  112. /* wolfSSL Client loop */
  113. static int client_loop(void)
  114. {
  115. /* set up client */
  116. int ret;
  117. const char* helloStr = "hello iot-safe wolfSSL";
  118. #if (IOTSAFE_ID_SIZE == 1)
  119. byte cert_file_id, privkey_id, keypair_id, peer_pubkey_id, peer_cert_id, serv_cert_id;
  120. byte ca_cert_id;
  121. #else
  122. word16 cert_file_id, privkey_id, keypair_id, peer_pubkey_id, peer_cert_id, serv_cert_id;
  123. word16 ca_cert_id;
  124. #endif
  125. cert_file_id = CRT_CLIENT_FILE_ID;
  126. privkey_id = PRIVKEY_ID;
  127. keypair_id = ECDH_KEYPAIR_ID;
  128. peer_pubkey_id = PEER_PUBKEY_ID;
  129. peer_cert_id = PEER_CERT_ID;
  130. ca_cert_id = CRT_SERVER_FILE_ID;
  131. serv_cert_id = CRT_SERVER_FILE_ID;
  132. printf("=== CLIENT step %d ===\n", client_state);
  133. if (client_state == 0) {
  134. printf("Client: Creating new CTX\n");
  135. #ifdef WOLFSSL_TLS13
  136. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  137. #else
  138. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
  139. #endif
  140. if (cli_ctx == NULL) {
  141. printf("Bad client ctx new");
  142. return 0;
  143. }
  144. printf("Client: Enabling IoT Safe in CTX\n");
  145. wolfSSL_CTX_iotsafe_enable(cli_ctx);
  146. printf("Loading CA\n");
  147. #ifdef SOFT_SERVER_CA
  148. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256,
  149. sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
  150. if (ret != WOLFSSL_SUCCESS) {
  151. printf("Bad CA\n");
  152. return -1;
  153. }
  154. #else
  155. cert_buffer_size = wolfIoTSafe_GetCert_ex(&ca_cert_id, IOTSAFE_ID_SIZE,
  156. cert_buffer,
  157. sizeof(cert_buffer));
  158. if (cert_buffer_size < 1) {
  159. printf("Bad server cert\n");
  160. return -1;
  161. }
  162. printf("Loaded Server CA from IoT-Safe, size = %lu\n",
  163. cert_buffer_size);
  164. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, cert_buffer,
  165. cert_buffer_size, WOLFSSL_FILETYPE_ASN1);
  166. #endif
  167. printf("Loading Server Certificate\n");
  168. #ifdef SOFT_SERVER_CERT
  169. /*
  170. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, serv_ecc_der_256,
  171. sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
  172. if (ret != WOLFSSL_SUCCESS) {
  173. printf("Bad Server certificate!\n");
  174. return -1;
  175. }
  176. */
  177. #else
  178. cert_buffer_size = wolfIoTSafe_GetCert_ex(&serv_cert_id,IOTSAFE_ID_SIZE,
  179. cert_buffer,
  180. sizeof(cert_buffer));
  181. if (cert_buffer_size < 1) {
  182. printf("Bad server certificate!\n");
  183. return -1;
  184. }
  185. printf("Loaded Server certificate from IoT-Safe, size = %lu\n",
  186. cert_buffer_size);
  187. if (wolfSSL_CTX_load_verify_buffer(cli_ctx, cert_buffer, cert_buffer_size,
  188. WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  189. printf("Cannot load server cert\n");
  190. return -1;
  191. }
  192. #endif
  193. printf("Server certificate successfully imported.\n");
  194. wolfSSL_CTX_set_verify(cli_ctx, WOLFSSL_VERIFY_PEER, NULL);
  195. #ifdef CLIENT_AUTH
  196. cert_buffer_size = wolfIoTSafe_GetCert_ex(&cert_file_id, IOTSAFE_ID_SIZE,
  197. cert_buffer,
  198. sizeof(cert_buffer));
  199. if (cert_buffer_size < 1) {
  200. printf("Bad client cert\n");
  201. return -1;
  202. }
  203. printf("Loaded Client certificate from IoT-Safe, size = %lu\n",
  204. cert_buffer_size);
  205. if (wolfSSL_CTX_use_certificate_buffer(cli_ctx, cert_buffer,
  206. cert_buffer_size, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  207. printf("Cannot load client cert\n");
  208. return -1;
  209. }
  210. printf("Client certificate successfully imported.\n");
  211. #endif
  212. /* Setting IO Send/Receive functions to local memory-based message
  213. * passing (ClientSend, ClientRecv) */
  214. wolfSSL_CTX_SetIOSend(cli_ctx, ClientSend);
  215. wolfSSL_CTX_SetIORecv(cli_ctx, ClientRecv);
  216. printf("Creating new SSL object\n");
  217. cli_ssl = wolfSSL_new(cli_ctx);
  218. if (cli_ssl == NULL) {
  219. printf("bad client new");
  220. return 0;
  221. }
  222. printf("Setting TLS options: turn on IoT-safe for this socket\n");
  223. wolfSSL_iotsafe_on_ex(cli_ssl, &privkey_id, &keypair_id,
  224. &peer_pubkey_id, &peer_cert_id, IOTSAFE_ID_SIZE);
  225. #ifdef WOLFSSL_TLS13
  226. printf("Setting TLSv1.3 for SECP256R1 key share\n");
  227. wolfSSL_UseKeyShare(cli_ssl, WOLFSSL_ECC_SECP256R1);
  228. #endif
  229. client_state++;
  230. }
  231. if (client_state == 1) {
  232. printf("Connecting to server...\n");
  233. ret = wolfSSL_connect(cli_ssl);
  234. if (ret != WOLFSSL_SUCCESS) {
  235. if (wolfSSL_want_read(cli_ssl) || wolfSSL_want_write(cli_ssl)) {
  236. return 0;
  237. }
  238. printf("Error in client tls connect: %d\n",
  239. wolfSSL_get_error(cli_ssl, ret));
  240. client_state = 0;
  241. return -1;
  242. }
  243. printf("Client connected!\n");
  244. client_state++;
  245. }
  246. if (client_state == 2) {
  247. printf("Sending message: %s\n", helloStr);
  248. ret = wolfSSL_write(cli_ssl, helloStr, XSTRLEN(helloStr));
  249. if (ret >= 0) {
  250. printf("wolfSSL client test success!\n");
  251. wolfSSL_free(cli_ssl); cli_ssl = NULL;
  252. wolfSSL_CTX_free(cli_ctx); cli_ctx = NULL;
  253. client_state = 0;
  254. }
  255. else if (wolfSSL_get_error(cli_ssl, ret) != WOLFSSL_ERROR_WANT_WRITE) {
  256. printf("Error in client tls write");
  257. client_state = 0;
  258. return -1;
  259. }
  260. }
  261. return ret;
  262. }
  263. /* wolfSSL Server Loop */
  264. static int server_loop(void)
  265. {
  266. int ret;
  267. unsigned char buf[80];
  268. printf("=== SERVER step %d ===\n", server_state);
  269. if (server_state == 0) {
  270. #ifdef WOLFSSL_TLS13
  271. srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  272. #else
  273. srv_ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
  274. #endif
  275. if (srv_ctx == NULL) {
  276. printf("bad server ctx new");
  277. return -1;
  278. }
  279. #ifdef CLIENT_AUTH
  280. ret = wolfSSL_CTX_load_verify_buffer(srv_ctx, ca_ecc_cert_der_256,
  281. sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
  282. if (ret != WOLFSSL_SUCCESS) {
  283. printf("Bad CA load: %d\n", ret);
  284. }
  285. ret = wolfSSL_CTX_load_verify_buffer(srv_ctx, cliecc_cert_der_256,
  286. sizeof_cliecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
  287. if (ret != WOLFSSL_SUCCESS) {
  288. printf("Bad Client cert load: %d\n", ret);
  289. }
  290. wolfSSL_CTX_set_verify(srv_ctx, WOLFSSL_VERIFY_PEER, NULL);
  291. #endif
  292. if (wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, ecc_key_der_256,
  293. sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  294. printf("Cannot load server private key\n");
  295. }
  296. if (wolfSSL_CTX_use_certificate_buffer(srv_ctx, serv_ecc_der_256,
  297. sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) {
  298. printf("Cannot load server cert\n");
  299. }
  300. wolfSSL_CTX_SetIOSend(srv_ctx, ServerSend);
  301. wolfSSL_CTX_SetIORecv(srv_ctx, ServerRecv);
  302. srv_ssl = wolfSSL_new(srv_ctx);
  303. if (srv_ssl == NULL) {
  304. printf("bad server new");
  305. return -1;
  306. }
  307. #ifdef WOLFSSL_TLS13
  308. printf("Setting TLSv1.3 for SECP256R1 key share\n");
  309. wolfSSL_UseKeyShare(srv_ssl, WOLFSSL_ECC_SECP256R1);
  310. #endif
  311. server_state++;
  312. }
  313. if (server_state == 1) {
  314. /* accept tls connection without tcp sockets */
  315. ret = wolfSSL_accept(srv_ssl);
  316. if (ret != WOLFSSL_SUCCESS) {
  317. if (wolfSSL_want_read(srv_ssl) || wolfSSL_want_write(srv_ssl)) {
  318. return 0;
  319. }
  320. printf("Error in server tls accept: %d\n",
  321. wolfSSL_get_error(srv_ssl, ret));
  322. server_state = 0;
  323. return -1;
  324. }
  325. printf("wolfSSL accept success!\n");
  326. server_state++;
  327. }
  328. if (server_state == 2) {
  329. ret = wolfSSL_read(srv_ssl, buf, sizeof(buf)-1);
  330. if (wolfSSL_get_error(srv_ssl, ret) == WOLFSSL_ERROR_WANT_READ) {
  331. return 0;
  332. }
  333. if (ret < 0) {
  334. printf("SERVER READ ERROR: %d\n", wolfSSL_get_error(srv_ssl, ret));
  335. return -1;
  336. }
  337. if (ret > 0) {
  338. printf("++++++ Server received msg from client: '%s'\n", buf);
  339. printf("IoT-Safe TEST SUCCESSFUL\n");
  340. wolfSSL_free(srv_ssl); srv_ssl = NULL;
  341. wolfSSL_CTX_free(srv_ctx); srv_ctx = NULL;
  342. server_state = 0;
  343. return -1; /* exit test loop, so it doesn't keep running forever */
  344. }
  345. }
  346. return 0;
  347. }
  348. int memory_tls_test(void)
  349. {
  350. int ret_s, ret_c;
  351. printf("Starting memory-tls test...\n");
  352. do {
  353. ret_s = server_loop();
  354. if (ret_s >= 0)
  355. ret_c = client_loop();
  356. } while ((ret_s >= 0) && (ret_c >= 0));
  357. /* clean up */
  358. wolfSSL_free(cli_ssl);
  359. wolfSSL_CTX_free(cli_ctx);
  360. wolfSSL_free(srv_ssl);
  361. wolfSSL_CTX_free(srv_ctx);
  362. return 0;
  363. }