client-tls.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /* client-tls.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. #include "client-tls.h"
  22. /* Espressif FreeRTOS */
  23. #ifndef SINGLE_THREADED
  24. #include <freertos/FreeRTOS.h>
  25. #include <freertos/task.h>
  26. #include <freertos/event_groups.h>
  27. #endif
  28. /* Espressif */
  29. #include <esp_log.h>
  30. /* socket includes */
  31. #include <lwip/netdb.h>
  32. #include <lwip/sockets.h>
  33. /* wolfSSL */
  34. #include <wolfssl/wolfcrypt/settings.h>
  35. #include <wolfssl/ssl.h>
  36. #if defined(WOLFSSL_WC_KYBER)
  37. #include <wolfssl/wolfcrypt/kyber.h>
  38. #include <wolfssl/wolfcrypt/wc_kyber.h>
  39. #endif
  40. #if defined(USE_CERT_BUFFERS_2048) || defined(USE_CERT_BUFFERS_1024)
  41. #include <wolfssl/certs_test.h>
  42. #endif
  43. #ifdef WOLFSSL_TRACK_MEMORY
  44. #include <wolfssl/wolfcrypt/mem_track.h>
  45. #endif
  46. #ifndef NO_DH
  47. /* see also wolfssl/test.h */
  48. #undef DEFAULT_MIN_DHKEY_BITS
  49. #define DEFAULT_MIN_DHKEY_BITS 1024
  50. #undef DEFAULT_MAX_DHKEY_BITS
  51. #define DEFAULT_MAX_DHKEY_BITS 2048
  52. #endif
  53. /* Project */
  54. #include "wifi_connect.h"
  55. #include "time_helper.h"
  56. /* working TLS 1.2 VS client app commandline param:
  57. *
  58. * -h 192.168.1.128 -v 3 -l ECDHE-ECDSA-SM4-CBC-SM3 -c ./certs/sm2/client-sm2.pem -k ./certs/sm2/client-sm2-priv.pem -A ./certs/sm2/root-sm2.pem -C
  59. *
  60. * working Linux, non-working VS c app
  61. *
  62. * -h 192.168.1.128 -v 4 -l TLS13-SM4-CCM-SM3 -c ./certs/sm2/client-sm2.pem -k ./certs/sm2/client-sm2-priv.pem -A ./certs/sm2/root-sm2.pem -C
  63. *
  64. **/
  65. #define TAG "client-tls"
  66. #if defined(DEBUG_WOLFSSL)
  67. int stack_start = -1;
  68. int ShowCiphers(WOLFSSL* ssl)
  69. {
  70. #define CLIENT_TLS_MAX_CIPHER_LENGTH 4096
  71. char ciphers[CLIENT_TLS_MAX_CIPHER_LENGTH];
  72. const char* cipher_used;
  73. int ret = 0;
  74. if (ssl == NULL) {
  75. ESP_LOGI(TAG, "WOLFSSL* ssl is NULL, so no cipher in use");
  76. ret = wolfSSL_get_ciphers(ciphers, (int)sizeof(ciphers));
  77. if (ret == WOLFSSL_SUCCESS) {
  78. for (int i = 0; i < CLIENT_TLS_MAX_CIPHER_LENGTH; i++) {
  79. if (ciphers[i] == ':') {
  80. ciphers[i] = '\n';
  81. }
  82. }
  83. ESP_LOGI(TAG, "Available Ciphers:\n%s\n", ciphers);
  84. }
  85. else {
  86. ESP_LOGE(TAG, "Failed to call wolfSSL_get_ciphers. Error %d", ret);
  87. }
  88. }
  89. else {
  90. cipher_used = wolfSSL_get_cipher_name(ssl);
  91. ESP_LOGI(TAG, "WOLFSSL* ssl using %s", cipher_used);
  92. }
  93. return ret;
  94. }
  95. #endif
  96. #if defined(WOLFSSL_ESPWROOM32SE) && defined(HAVE_PK_CALLBACKS) \
  97. && defined(WOLFSSL_ATECC508A)
  98. #include "wolfssl/wolfcrypt/port/atmel/atmel.h"
  99. /* when you want to use custom slot allocation */
  100. /* enable the definition CUSTOM_SLOT_ALLOCATION.*/
  101. #if defined(CUSTOM_SLOT_ALLOCATION)
  102. static byte mSlotList[ATECC_MAX_SLOT];
  103. int atmel_set_slot_allocator(atmel_slot_alloc_cb alloc,
  104. atmel_slot_dealloc_cb dealloc);
  105. /* initialize slot array */
  106. void my_atmel_slotInit()
  107. {
  108. int i;
  109. for (i = 0; i < ATECC_MAX_SLOT; i++) {
  110. mSlotList[i] = ATECC_INVALID_SLOT;
  111. }
  112. }
  113. /* allocate slot depending on slotType */
  114. int my_atmel_alloc(int slotType)
  115. {
  116. int i, slot = -1;
  117. switch (slotType) {
  118. case ATMEL_SLOT_ENCKEY:
  119. slot = 2;
  120. break;
  121. case ATMEL_SLOT_DEVICE:
  122. slot = 0;
  123. break;
  124. case ATMEL_SLOT_ECDHE:
  125. slot = 0;
  126. break;
  127. case ATMEL_SLOT_ECDHE_ENC:
  128. slot = 4;
  129. break;
  130. case ATMEL_SLOT_ANY:
  131. for (i = 0; i < ATECC_MAX_SLOT; i++) {
  132. if (mSlotList[i] == ATECC_INVALID_SLOT) {
  133. slot = i;
  134. break;
  135. }
  136. }
  137. }
  138. return slot;
  139. }
  140. /* free slot array */
  141. void my_atmel_free(int slotId)
  142. {
  143. if (slotId >= 0 && slotId < ATECC_MAX_SLOT) {
  144. mSlotList[slotId] = ATECC_INVALID_SLOT;
  145. }
  146. }
  147. #endif /* CUSTOM_SLOT_ALLOCATION */
  148. #endif /* WOLFSSL_ESPWROOM32SE && HAVE_PK_CALLBACK && WOLFSSL_ATECC508A */
  149. /* client task */
  150. WOLFSSL_ESP_TASK tls_smp_client_task(void* args)
  151. {
  152. #if defined(SINGLE_THREADED)
  153. int ret = ESP_OK;
  154. #define TLS_SMP_CLIENT_TASK_RET ret
  155. #else
  156. #define TLS_SMP_CLIENT_TASK_RET
  157. #endif
  158. char buff[256];
  159. const char sndMsg[] = "GET /index.html HTTP/1.0\r\n\r\n";
  160. const char* ch = TLS_SMP_TARGET_HOST; /* see wifi_connect.h */
  161. struct sockaddr_in servAddr;
  162. struct hostent *hp;
  163. struct ip4_addr *ip4_addr;
  164. int ret_i; /* interim return values */
  165. int err; /* interim return values */
  166. int sockfd;
  167. int doPeerCheck;
  168. int sendGet;
  169. #ifdef DEBUG_WOLFSSL
  170. int this_heap = 0;
  171. #endif
  172. #ifndef NO_DH
  173. int minDhKeyBits = DEFAULT_MIN_DHKEY_BITS;
  174. #endif
  175. /* declare wolfSSL objects */
  176. WOLFSSL_CTX* ctx;
  177. WOLFSSL* ssl;
  178. size_t len;
  179. wolfSSL_Debugging_ON();
  180. WOLFSSL_ENTER(TLS_SMP_CLIENT_TASK_NAME);
  181. doPeerCheck = 1;
  182. sendGet = 0;
  183. #ifdef DEBUG_WOLFSSL
  184. WOLFSSL_MSG("Debug ON");
  185. ShowCiphers(NULL);
  186. #endif
  187. /* Initialize wolfSSL */
  188. wolfSSL_Init();
  189. /* Create a socket that uses an Internet IPv4 address,
  190. * Sets the socket to be stream based (TCP),
  191. * 0 means choose the default protocol. */
  192. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  193. ESP_LOGE(TAG, "ERROR: failed to create the socket\n");
  194. }
  195. ESP_LOGI(TAG, "get target IP address");
  196. hp = gethostbyname(TLS_SMP_TARGET_HOST);
  197. if (!hp) {
  198. ESP_LOGE(TAG, "Failed to get host name.");
  199. ip4_addr = NULL;
  200. }
  201. else {
  202. ip4_addr = (struct ip4_addr *)hp->h_addr;
  203. }
  204. /* Create and initialize WOLFSSL_CTX */
  205. ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); /* SSL 3.0 - TLS 1.3. */
  206. /* options: */
  207. /* ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); only TLS 1.2 */
  208. /* ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); only TLS 1.3 */
  209. /* wolfSSL_CTX_NoTicketTLSv12(); */
  210. /* wolfSSL_NoTicketTLSv12(); */
  211. if (ctx == NULL) {
  212. ESP_LOGE(TAG, "ERROR: failed to create WOLFSSL_CTX\n");
  213. }
  214. #if defined(WOLFSSL_ESP32_CIPHER_SUITE)
  215. ESP_LOGI(TAG, "Start SM2\n");
  216. /*
  217. *
  218. * reference code for SM Ciphers:
  219. *
  220. #if defined(HAVE_AESGCM) && !defined(NO_DH)
  221. #ifdef WOLFSSL_TLS13
  222. defaultCipherList = "TLS13-AES128-GCM-SHA256"
  223. #ifndef WOLFSSL_NO_TLS12
  224. ":DHE-PSK-AES128-GCM-SHA256"
  225. #endif
  226. ;
  227. #else
  228. defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
  229. #endif
  230. #elif defined(HAVE_AESGCM) && defined(WOLFSSL_TLS13)
  231. defaultCipherList = "TLS13-AES128-GCM-SHA256:PSK-AES128-GCM-SHA256"
  232. #ifndef WOLFSSL_NO_TLS12
  233. ":PSK-AES128-GCM-SHA256"
  234. #endif
  235. ;
  236. #elif defined(HAVE_NULL_CIPHER)
  237. defaultCipherList = "PSK-NULL-SHA256";
  238. #elif !defined(NO_AES_CBC)
  239. defaultCipherList = "PSK-AES128-CBC-SHA256";
  240. #else
  241. defaultCipherList = "PSK-AES128-GCM-SHA256";
  242. #endif
  243. */
  244. ret = wolfSSL_CTX_set_cipher_list(ctx, WOLFSSL_ESP32_CIPHER_SUITE);
  245. if (ret == WOLFSSL_SUCCESS) {
  246. ESP_LOGI(TAG, "Set cipher list: %s\n", WOLFSSL_ESP32_CIPHER_SUITE);
  247. }
  248. else {
  249. ESP_LOGE(TAG, "ERROR: failed to set cipher list: %s\n",
  250. WOLFSSL_ESP32_CIPHER_SUITE);
  251. }
  252. #endif
  253. #ifdef DEBUG_WOLFSSL
  254. ShowCiphers(NULL);
  255. ESP_LOGI(TAG, "Stack used: %d\n",
  256. CONFIG_ESP_MAIN_TASK_STACK_SIZE
  257. - uxTaskGetStackHighWaterMark(NULL));
  258. #endif
  259. /* see user_settings PROJECT_DH for HAVE_DH and HAVE_FFDHE_2048 */
  260. #ifndef NO_DH
  261. ret = wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits);
  262. if (ret != SSL_SUCCESS) {
  263. ESP_LOGE(TAG, "Error setting minimum DH key size");
  264. }
  265. #endif
  266. /* no peer check */
  267. if (doPeerCheck == 0) {
  268. ESP_LOGW(TAG, "doPeerCheck == 0");
  269. wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, 0);
  270. }
  271. else {
  272. ESP_LOGW(TAG, "doPeerCheck != 0");
  273. WOLFSSL_MSG("Loading... our cert");
  274. /* load our certificate */
  275. ret_i = wolfSSL_CTX_use_certificate_chain_buffer_format(ctx,
  276. CTX_CLIENT_CERT,
  277. CTX_CLIENT_CERT_SIZE,
  278. CTX_CLIENT_CERT_TYPE);
  279. if (ret_i != SSL_SUCCESS) {
  280. ESP_LOGE(TAG, "ERROR: failed to load chain %d, "
  281. "please check the file.", ret_i);
  282. }
  283. /* Load client certificates into WOLFSSL_CTX */
  284. WOLFSSL_MSG("Loading...cert");
  285. ret_i = wolfSSL_CTX_load_verify_buffer(ctx,
  286. CTX_CA_CERT,
  287. CTX_CA_CERT_SIZE,
  288. CTX_CA_CERT_TYPE);
  289. ret_i = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
  290. CTX_CLIENT_KEY,
  291. CTX_CLIENT_KEY_SIZE,
  292. CTX_CLIENT_KEY_TYPE);
  293. if(ret_i != SSL_SUCCESS) {
  294. wolfSSL_CTX_free(ctx) ; ctx = NULL ;
  295. ESP_LOGE(TAG, "ERROR: failed to load key %d, "
  296. "please check the file.\n", ret_i) ;
  297. }
  298. wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, 0);
  299. }
  300. /* Initialize the server address struct with zeros */
  301. memset(&servAddr, 0, sizeof(servAddr));
  302. /* Fill in the server address */
  303. servAddr.sin_family = AF_INET; /* using IPv4 */
  304. servAddr.sin_port = htons(TLS_SMP_DEFAULT_PORT); /* on DEFAULT_PORT */
  305. if (*ch >= '1' && *ch <= '9') {
  306. /* Get the server IPv4 address from the command line call */
  307. WOLFSSL_MSG("inet_pton");
  308. if ((ret_i = inet_pton(AF_INET,
  309. TLS_SMP_TARGET_HOST,
  310. &servAddr.sin_addr)) != 1) {
  311. ESP_LOGE(TAG, "ERROR: invalid address ret=%d\n", ret_i);
  312. }
  313. }
  314. else {
  315. servAddr.sin_addr.s_addr = ip4_addr->addr;
  316. }
  317. /* Connect to the server */
  318. sprintf(buff,
  319. "Connecting to server....%s (port:%d)",
  320. TLS_SMP_TARGET_HOST,
  321. TLS_SMP_DEFAULT_PORT);
  322. ESP_LOGI(TAG, "%s\n", buff);
  323. if ((ret_i = connect(sockfd,
  324. (struct sockaddr *)&servAddr,
  325. sizeof(servAddr))) == -1) {
  326. ESP_LOGE(TAG, "ERROR: failed to connect ret=%d\n", ret_i);
  327. }
  328. #if defined(WOLFSSL_EXPERIMENTAL_SETTINGS)
  329. ESP_LOGW(TAG, "WOLFSSL_EXPERIMENTAL_SETTINGS is enabled");
  330. #endif
  331. WOLFSSL_MSG("Create a WOLFSSL object");
  332. /* Create a WOLFSSL object */
  333. if ((ssl = wolfSSL_new(ctx)) == NULL) {
  334. ESP_LOGE(TAG, "ERROR: failed to create WOLFSSL object\n");
  335. }
  336. else {
  337. #ifdef DEBUG_WOLFSSL
  338. ESP_LOGI(TAG, "\nCreated WOLFSSL object:");
  339. ShowCiphers(ssl);
  340. this_heap = esp_get_free_heap_size();
  341. ESP_LOGI(TAG, "tls_smp_client_task heap @ %p = %d",
  342. &this_heap, this_heap);
  343. #endif
  344. #if defined(WOLFSSL_HAVE_KYBER)
  345. #if defined(WOLFSSL_KYBER1024)
  346. ESP_LOGI(TAG, "WOLFSSL_HAVE_KYBER is enabled, setting key share: "
  347. "WOLFSSL_P256_KYBER_LEVEL5");
  348. ret_i = wolfSSL_UseKeyShare(ssl, WOLFSSL_P521_KYBER_LEVEL5);
  349. #elif defined(WOLFSSL_KYBER768)
  350. ESP_LOGI(TAG, "WOLFSSL_HAVE_KYBER is enabled, setting key share: "
  351. "WOLFSSL_P256_KYBER_LEVEL3");
  352. ret_i = wolfSSL_UseKeyShare(ssl, WOLFSSL_P256_KYBER_LEVEL3);
  353. #elif defined(WOLFSSL_KYBER512)
  354. /* This will typically be a low memory situation, such as ESP8266 */
  355. ESP_LOGI(TAG, "WOLFSSL_HAVE_KYBER is enabled, setting key share: "
  356. "WOLFSSL_P256_KYBER_LEVEL1");
  357. ret_i = wolfSSL_UseKeyShare(ssl, WOLFSSL_P256_KYBER_LEVEL1);
  358. #else
  359. ESP_LOGW(TAG, "WOLFSSL_HAVE_KYBER enabled but no key size available.");
  360. ret_i = ESP_FAIL;
  361. #endif
  362. if (ret_i == SSL_SUCCESS) {
  363. ESP_LOGI(TAG, "UseKeyShare Kyber success");
  364. }
  365. else {
  366. ESP_LOGE(TAG, "UseKeyShare Kyber failed");
  367. }
  368. #else
  369. ESP_LOGI(TAG, "WOLFSSL_HAVE_KYBER is not enabled");
  370. #endif
  371. }
  372. #if defined(WOLFSSL_SM2)
  373. /* SM TLS1.3 Cipher needs to have key share explicitly set. */
  374. ret = wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SM2P256V1);
  375. if (ret == WOLFSSL_SUCCESS) {
  376. ESP_LOGI(TAG, "Successfully set WOLFSSL_ECC_SM2P256V1");
  377. }
  378. else {
  379. ESP_LOGE(TAG, "FAILED to set WOLFSSL_ECC_SM2P256V1");
  380. }
  381. #endif
  382. /* when using atecc608a on esp32-wroom-32se */
  383. #if defined(WOLFSSL_ESPWROOM32SE) && defined(HAVE_PK_CALLBACKS) \
  384. && defined(WOLFSSL_ATECC508A)
  385. atcatls_set_callbacks(ctx);
  386. /* when using custom slot-allocation */
  387. #if defined(CUSTOM_SLOT_ALLOCATION)
  388. my_atmel_slotInit();
  389. atmel_set_slot_allocator(my_atmel_alloc, my_atmel_free);
  390. #endif
  391. #endif
  392. #ifdef DEBUG_WOLFSSL
  393. this_heap = esp_get_free_heap_size();
  394. ESP_LOGI(TAG, "tls_smp_client_task heap(2) @ %p = %d",
  395. &this_heap, this_heap);
  396. #endif
  397. /* Attach wolfSSL to the socket */
  398. ret_i = wolfSSL_set_fd(ssl, sockfd);
  399. if (ret_i == WOLFSSL_SUCCESS) {
  400. ESP_LOGI(TAG, "wolfSSL_set_fd success");
  401. }
  402. else {
  403. ESP_LOGE(TAG, "ERROR: failed wolfSSL_set_fd. Error: %d\n", ret_i);
  404. }
  405. ESP_LOGI(TAG, "Connect to wolfSSL server...");
  406. ret_i = wolfSSL_connect(ssl);
  407. #ifdef DEBUG_WOLFSSL
  408. this_heap = esp_get_free_heap_size();
  409. ESP_LOGI(TAG, "tls_smp_client_task heap(3) @ %p = %d",
  410. &this_heap, this_heap);
  411. #endif
  412. if (ret_i == SSL_SUCCESS) {
  413. #ifdef DEBUG_WOLFSSL
  414. ShowCiphers(ssl);
  415. #endif
  416. ESP_LOGI(TAG, "Connect success! Sending message...");
  417. /* Get a message for the server from stdin */
  418. WOLFSSL_MSG("Message for server: ");
  419. memset(buff, 0, sizeof(buff));
  420. if (sendGet) {
  421. len = XSTRLEN(sndMsg);
  422. strncpy(buff, sndMsg, len);
  423. }
  424. else {
  425. sprintf(buff, "Hello from Espressif wolfSSL TLS client!\n");
  426. len = strnlen(buff, sizeof(buff));
  427. }
  428. buff[len] = '\0';
  429. ESP_LOGI(TAG, "SSL connect ok, sending message:\n\n%s\n", buff);
  430. /* Send the message to the server */
  431. do {
  432. err = 0; /* reset error */
  433. ret_i = wolfSSL_write(ssl, buff, len);
  434. if (ret_i <= 0) {
  435. err = wolfSSL_get_error(ssl, 0);
  436. }
  437. } while (err == WOLFSSL_ERROR_WANT_WRITE ||
  438. err == WOLFSSL_ERROR_WANT_READ);
  439. if (ret_i != len) {
  440. ESP_LOGE(TAG, "ERROR: failed to write\n");
  441. }
  442. else {
  443. ESP_LOGI(TAG, "Message sent! Awaiting response...");
  444. }
  445. /* Read the server data into our buff array */
  446. memset(buff, 0, sizeof(buff));
  447. do {
  448. err = 0; /* reset error */
  449. ret_i =wolfSSL_read(ssl, buff, sizeof(buff));
  450. if (ret_i <= 0) {
  451. err = wolfSSL_get_error(ssl, 0);
  452. }
  453. } while ((err == WOLFSSL_ERROR_WANT_READ) ||
  454. (err == WOLFSSL_ERROR_WANT_WRITE) );
  455. if (ret_i < 0) {
  456. ESP_LOGE(TAG, "ERROR: failed to read\n");
  457. }
  458. /* Show any data the server sends */
  459. ESP_LOGI(TAG, "Server response: \n\n%s\n", buff);
  460. ret_i = wolfSSL_shutdown(ssl);
  461. while (ret_i == WOLFSSL_SHUTDOWN_NOT_DONE) {
  462. ret_i = wolfSSL_shutdown(ssl); /* bidirectional shutdown */
  463. if (ret_i == WOLFSSL_SUCCESS) {
  464. ESP_LOGI(TAG, "Bidirectional shutdown complete\n");
  465. break;
  466. }
  467. else if (ret_i != WOLFSSL_SHUTDOWN_NOT_DONE) {
  468. ESP_LOGE(TAG, "Bidirectional shutdown failed\n");
  469. break;
  470. }
  471. }
  472. if (ret_i != WOLFSSL_SUCCESS) {
  473. ESP_LOGE(TAG, "Bidirectional shutdown failed\n");
  474. }
  475. } /* wolfSSL_connect(ssl) == SSL_SUCCESS) */
  476. else {
  477. ESP_LOGE(TAG, "ERROR: failed to connect to wolfSSL. "
  478. "Error: %d\n", ret_i);
  479. }
  480. #ifdef DEBUG_WOLFSSL
  481. ShowCiphers(ssl);
  482. #endif
  483. ESP_LOGI(TAG, "Cleanup and exit");
  484. wolfSSL_free(ssl); /* Release the wolfSSL object memory */
  485. wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
  486. wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
  487. close(sockfd); /* Close the connection to the server */
  488. vTaskDelete(NULL);
  489. return TLS_SMP_CLIENT_TASK_RET;
  490. }
  491. #if defined(SINGLE_THREADED)
  492. /* we don't initialize a single thread, so no init function here */
  493. #else
  494. /* create task */
  495. WOLFSSL_ESP_TASK tls_smp_client_init(void* args)
  496. {
  497. int ret;
  498. #if ESP_IDF_VERSION_MAJOR >= 4
  499. TaskHandle_t _handle;
  500. #else
  501. xTaskHandle _handle;
  502. #endif
  503. /* See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos_idf.html#functions */
  504. if (TLS_SMP_CLIENT_TASK_BYTES < (6 * 1024)) {
  505. /* Observed approximately 6KB limit for the RTOS task stack size.
  506. * Reminder parameter is bytes, not words as with generic FreeeRTOS. */
  507. ESP_LOGW(TAG, "Warning: TLS_SMP_CLIENT_TASK_BYTES < 6KB");
  508. }
  509. #ifndef WOLFSSL_SMALL_STACK
  510. ESP_LOGW(TAG, "WARNING: WOLFSSL_SMALL_STACK is not defined. Consider "
  511. "defining that to reduce embedded memory usage.");
  512. #endif
  513. /* Note that despite vanilla FreeRTOS using WORDS for a parameter,
  514. * Espressif uses BYTES for the task stack size here.
  515. * See https://docs.espressif.com/projects/esp-idf/en/v4.3/esp32/api-reference/system/freertos.html */
  516. ret = xTaskCreate(tls_smp_client_task,
  517. TLS_SMP_CLIENT_TASK_NAME,
  518. TLS_SMP_CLIENT_TASK_BYTES,
  519. NULL,
  520. TLS_SMP_CLIENT_TASK_PRIORITY,
  521. &_handle);
  522. if (ret != pdPASS) {
  523. ESP_LOGI(TAG, "Create thread %s failed.", TLS_SMP_CLIENT_TASK_NAME);
  524. }
  525. return TLS_SMP_CLIENT_TASK_RET;
  526. }
  527. #endif