esp_tls_wolfssl.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <netdb.h>
  13. #include <http_parser.h>
  14. #include "esp_tls_wolfssl.h"
  15. #include "esp_tls_error_capture_internal.h"
  16. #include <errno.h>
  17. #include "esp_log.h"
  18. static unsigned char *global_cacert = NULL;
  19. static unsigned int global_cacert_pem_bytes = 0;
  20. static const char *TAG = "esp-tls-wolfssl";
  21. /* Prototypes for the static functions */
  22. static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls);
  23. #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
  24. #include "freertos/semphr.h"
  25. static SemaphoreHandle_t tls_conn_lock;
  26. static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* hint, char* identity,
  27. unsigned int id_max_len, unsigned char* key,unsigned int key_max_len);
  28. static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx);
  29. #ifdef WOLFSSL_TLS13
  30. #define PSK_MAX_ID_LEN 128
  31. #else
  32. #define PSK_MAX_ID_LEN 64
  33. #endif
  34. #define PSK_MAX_KEY_LEN 64
  35. static char psk_id_str[PSK_MAX_ID_LEN];
  36. static uint8_t psk_key_array[PSK_MAX_KEY_LEN];
  37. static uint8_t psk_key_max_len = 0;
  38. #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */
  39. static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls);
  40. /* This function shall return the error message when appropriate log level has been set otherwise this function shall do nothing */
  41. static void wolfssl_print_error_msg(int error)
  42. {
  43. #if (CONFIG_LOG_DEFAULT_LEVEL_DEBUG || CONFIG_LOG_DEFAULT_LEVEL_VERBOSE)
  44. static char error_buf[100];
  45. ESP_LOGE(TAG, "(%d) : %s", error, ERR_error_string(error, error_buf));
  46. #endif
  47. }
  48. typedef enum x509_file_type {
  49. FILE_TYPE_CA_CERT = 0, /* CA certificate to authenticate entity at other end */
  50. FILE_TYPE_SELF_CERT, /* Self certificate of the entity */
  51. FILE_TYPE_SELF_KEY, /* Private key in the self cert-key pair */
  52. } x509_file_type_t;
  53. /* Error type conversion utility so that esp-tls read/write API to return negative number on error */
  54. static inline ssize_t esp_tls_convert_wolfssl_err_to_ssize(int wolfssl_error)
  55. {
  56. switch (wolfssl_error) {
  57. case WOLFSSL_ERROR_WANT_READ:
  58. return ESP_TLS_ERR_SSL_WANT_READ;
  59. case WOLFSSL_ERROR_WANT_WRITE:
  60. return ESP_TLS_ERR_SSL_WANT_WRITE;
  61. default:
  62. // Make sure we return a negative number
  63. return wolfssl_error>0 ? -wolfssl_error: wolfssl_error;
  64. }
  65. }
  66. /* Checks whether the certificate provided is in pem format or not */
  67. static esp_err_t esp_load_wolfssl_verify_buffer(esp_tls_t *tls, const unsigned char *cert_buf, unsigned int cert_len, x509_file_type_t type, int *err_ret)
  68. {
  69. int wolf_fileformat = WOLFSSL_FILETYPE_DEFAULT;
  70. if (type == FILE_TYPE_SELF_KEY) {
  71. if (cert_buf[cert_len - 1] == '\0' && strstr( (const char *) cert_buf, "-----BEGIN " )) {
  72. wolf_fileformat = WOLFSSL_FILETYPE_PEM;
  73. } else {
  74. wolf_fileformat = WOLFSSL_FILETYPE_ASN1;
  75. }
  76. if ((*err_ret = wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) {
  77. return ESP_OK;
  78. }
  79. return ESP_FAIL;
  80. } else {
  81. if (cert_buf[cert_len - 1] == '\0' && strstr( (const char *) cert_buf, "-----BEGIN CERTIFICATE-----" )) {
  82. wolf_fileformat = WOLFSSL_FILETYPE_PEM;
  83. } else {
  84. wolf_fileformat = WOLFSSL_FILETYPE_ASN1;
  85. }
  86. if (type == FILE_TYPE_SELF_CERT) {
  87. if ((*err_ret = wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) {
  88. return ESP_OK;
  89. }
  90. return ESP_FAIL;
  91. } else if (type == FILE_TYPE_CA_CERT) {
  92. if ((*err_ret = wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cert_buf, cert_len, wolf_fileformat)) == WOLFSSL_SUCCESS) {
  93. return ESP_OK;
  94. }
  95. return ESP_FAIL;
  96. } else {
  97. /* Wrong file type provided */
  98. return ESP_FAIL;
  99. }
  100. }
  101. }
  102. void *esp_wolfssl_get_ssl_context(esp_tls_t *tls)
  103. {
  104. if (tls == NULL) {
  105. ESP_LOGE(TAG, "Invalid arguments");
  106. return NULL;
  107. }
  108. return (void*)tls->priv_ssl;
  109. }
  110. esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls, void *server_params)
  111. {
  112. #ifdef CONFIG_ESP_DEBUG_WOLFSSL
  113. wolfSSL_Debugging_ON();
  114. #endif
  115. assert(cfg != NULL);
  116. assert(tls != NULL);
  117. esp_err_t esp_ret = ESP_FAIL;
  118. int ret;
  119. ret = wolfSSL_Init();
  120. if (ret != WOLFSSL_SUCCESS) {
  121. ESP_LOGE(TAG, "Init wolfSSL failed: 0x%04X", ret);
  122. wolfssl_print_error_msg(ret);
  123. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  124. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
  125. goto exit;
  126. }
  127. if (tls->role == ESP_TLS_CLIENT) {
  128. esp_ret = set_client_config(hostname, hostlen, (esp_tls_cfg_t *)cfg, tls);
  129. if (esp_ret != ESP_OK) {
  130. ESP_LOGE(TAG, "Failed to set client configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
  131. goto exit;
  132. }
  133. } else if (tls->role == ESP_TLS_SERVER) {
  134. esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls);
  135. if (esp_ret != ESP_OK) {
  136. ESP_LOGE(TAG, "Failed to set server configurations, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
  137. goto exit;
  138. }
  139. }
  140. else {
  141. ESP_LOGE(TAG, "tls->role is not valid");
  142. goto exit;
  143. }
  144. return ESP_OK;
  145. exit:
  146. esp_wolfssl_cleanup(tls);
  147. return esp_ret;
  148. }
  149. static esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls)
  150. {
  151. int ret = WOLFSSL_FAILURE;
  152. #ifdef WOLFSSL_TLS13
  153. tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  154. #else
  155. tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_client_method());
  156. #endif
  157. if (!tls->priv_ctx) {
  158. ESP_LOGE(TAG, "Set wolfSSL ctx failed");
  159. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, ret);
  160. return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
  161. }
  162. if (cfg->crt_bundle_attach != NULL) {
  163. ESP_LOGE(TAG,"use_crt_bundle not supported in wolfssl");
  164. return ESP_FAIL;
  165. }
  166. if (cfg->use_global_ca_store == true) {
  167. if ((esp_load_wolfssl_verify_buffer(tls, global_cacert, global_cacert_pem_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
  168. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  169. ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
  170. wolfssl_print_error_msg(err);
  171. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  172. }
  173. wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
  174. } else if (cfg->cacert_buf != NULL) {
  175. if ((esp_load_wolfssl_verify_buffer(tls, cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
  176. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  177. ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
  178. wolfssl_print_error_msg(err);
  179. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  180. }
  181. wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
  182. } else if (cfg->psk_hint_key) {
  183. #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
  184. /*** PSK encryption mode is configured only if no certificate supplied and psk pointer not null ***/
  185. if(cfg->psk_hint_key->key == NULL || cfg->psk_hint_key->hint == NULL || cfg->psk_hint_key->key_size <= 0) {
  186. ESP_LOGE(TAG, "Please provide appropriate key, keysize and hint to use PSK");
  187. return ESP_FAIL;
  188. }
  189. /* mutex is given back when call back function executes or in case of failure (at cleanup) */
  190. if ((xSemaphoreTake(tls_conn_lock, 1000/portTICK_PERIOD_MS) != pdTRUE)) {
  191. ESP_LOGE(TAG, "tls_conn_lock could not be obtained in specified time");
  192. return -1;
  193. }
  194. ESP_LOGI(TAG, "setting psk configurations");
  195. if((cfg->psk_hint_key->key_size > PSK_MAX_KEY_LEN) || (strlen(cfg->psk_hint_key->hint) > PSK_MAX_ID_LEN)) {
  196. ESP_LOGE(TAG, "psk key length should be <= %d and identity hint length should be <= %d", PSK_MAX_KEY_LEN, PSK_MAX_ID_LEN);
  197. return ESP_ERR_INVALID_ARG;
  198. }
  199. psk_key_max_len = cfg->psk_hint_key->key_size;
  200. memset(psk_key_array, 0, sizeof(psk_key_array));
  201. memset(psk_id_str, 0, sizeof(psk_id_str));
  202. memcpy(psk_key_array, cfg->psk_hint_key->key, psk_key_max_len);
  203. memcpy(psk_id_str, cfg->psk_hint_key->hint, strlen(cfg->psk_hint_key->hint));
  204. wolfSSL_CTX_set_psk_client_callback( (WOLFSSL_CTX *)tls->priv_ctx, esp_wolfssl_psk_client_cb);
  205. if(esp_wolfssl_set_cipher_list( (WOLFSSL_CTX *)tls->priv_ctx) != ESP_OK) {
  206. ESP_LOGE(TAG, "error in setting cipher-list");
  207. return ESP_FAIL;
  208. }
  209. #else
  210. ESP_LOGE(TAG, "psk_hint_key configured but not enabled in menuconfig: Please enable ESP_TLS_PSK_VERIFICATION option");
  211. return ESP_ERR_INVALID_STATE;
  212. #endif
  213. } else {
  214. #ifdef CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY
  215. wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
  216. #else
  217. ESP_LOGE(TAG, "No server verification option set in esp_tls_cfg_t structure. Check esp_tls API reference");
  218. return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
  219. #endif
  220. }
  221. if (cfg->clientcert_buf != NULL && cfg->clientkey_buf != NULL) {
  222. if ((esp_load_wolfssl_verify_buffer(tls,cfg->clientcert_buf, cfg->clientcert_bytes, FILE_TYPE_SELF_CERT, &ret)) != ESP_OK) {
  223. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  224. ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
  225. wolfssl_print_error_msg(err);
  226. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  227. }
  228. if ((esp_load_wolfssl_verify_buffer(tls,cfg->clientkey_buf, cfg->clientkey_bytes, FILE_TYPE_SELF_KEY, &ret)) != ESP_OK) {
  229. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  230. ESP_LOGE(TAG, "Error in loading private key verify buffer, returned %d, error code: %d", ret, err);
  231. wolfssl_print_error_msg(err);
  232. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  233. }
  234. } else if (cfg->clientcert_buf != NULL || cfg->clientkey_buf != NULL) {
  235. ESP_LOGE(TAG, "You have to provide both clientcert_buf and clientkey_buf for mutual authentication");
  236. return ESP_FAIL;
  237. }
  238. tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx);
  239. if (!tls->priv_ssl) {
  240. ESP_LOGE(TAG, "Create wolfSSL failed");
  241. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  242. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
  243. return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
  244. }
  245. if (!cfg->skip_common_name) {
  246. char *use_host = NULL;
  247. if (cfg->common_name != NULL) {
  248. use_host = strdup(cfg->common_name);
  249. } else {
  250. use_host = strndup(hostname, hostlen);
  251. }
  252. if (use_host == NULL) {
  253. return ESP_ERR_NO_MEM;
  254. }
  255. /* Hostname set here should match CN in server certificate */
  256. if ((ret = (wolfSSL_check_domain_name( (WOLFSSL *)tls->priv_ssl, use_host))) != WOLFSSL_SUCCESS) {
  257. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  258. ESP_LOGE(TAG, "wolfSSL_check_domain_name returned %d, error code: %d", ret, err);
  259. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
  260. free(use_host);
  261. return ESP_ERR_WOLFSSL_SSL_SET_HOSTNAME_FAILED;
  262. }
  263. free(use_host);
  264. }
  265. if (cfg->alpn_protos) {
  266. #ifdef CONFIG_WOLFSSL_HAVE_ALPN
  267. char **alpn_list = (char **)cfg->alpn_protos;
  268. for (; *alpn_list != NULL; alpn_list ++) {
  269. ESP_LOGD(TAG, "alpn protocol is %s", *alpn_list);
  270. if ((ret = wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH)) != WOLFSSL_SUCCESS) {
  271. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  272. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
  273. ESP_LOGE(TAG, "wolfSSL UseALPN failed, returned %d, error code: %d", ret, err);
  274. wolfssl_print_error_msg(err);
  275. return ESP_ERR_WOLFSSL_SSL_CONF_ALPN_PROTOCOLS_FAILED;
  276. }
  277. }
  278. #else
  279. ESP_LOGE(TAG, "CONFIG_WOLFSSL_HAVE_ALPN not enabled in menuconfig");
  280. return ESP_FAIL;
  281. #endif /* CONFIG_WOLFSSL_HAVE_ALPN */
  282. }
  283. wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
  284. return ESP_OK;
  285. }
  286. static esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
  287. {
  288. int ret = WOLFSSL_FAILURE;
  289. #ifdef WOLFSSL_TLS13
  290. tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  291. #else
  292. tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method());
  293. #endif
  294. if (!tls->priv_ctx) {
  295. ESP_LOGE(TAG, "Set wolfSSL ctx failed");
  296. return ESP_ERR_WOLFSSL_CTX_SETUP_FAILED;
  297. }
  298. if (cfg->cacert_buf != NULL) {
  299. if ((esp_load_wolfssl_verify_buffer(tls,cfg->cacert_buf, cfg->cacert_bytes, FILE_TYPE_CA_CERT, &ret)) != ESP_OK) {
  300. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  301. ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
  302. wolfssl_print_error_msg(err);
  303. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  304. }
  305. wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
  306. ESP_LOGD(TAG," Verify Client for Mutual Auth");
  307. } else {
  308. ESP_LOGD(TAG," Not verifying Client ");
  309. wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
  310. }
  311. if (cfg->servercert_buf != NULL && cfg->serverkey_buf != NULL) {
  312. if ((esp_load_wolfssl_verify_buffer(tls,cfg->servercert_buf, cfg->servercert_bytes, FILE_TYPE_SELF_CERT, &ret)) != ESP_OK) {
  313. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  314. ESP_LOGE(TAG, "Error in loading certificate verify buffer, returned %d, error code: %d", ret, err);
  315. wolfssl_print_error_msg(err);
  316. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  317. }
  318. if ((esp_load_wolfssl_verify_buffer(tls,cfg->serverkey_buf, cfg->serverkey_bytes, FILE_TYPE_SELF_KEY, &ret)) != ESP_OK) {
  319. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  320. ESP_LOGE(TAG, "Error in loading private key verify buffer, returned %d, error code: %d", ret, err);
  321. wolfssl_print_error_msg(err);
  322. return ESP_ERR_WOLFSSL_CERT_VERIFY_SETUP_FAILED;
  323. }
  324. } else {
  325. ESP_LOGE(TAG, "You have to provide both servercert_buf and serverkey_buf for https_server");
  326. return ESP_FAIL;
  327. }
  328. tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx);
  329. if (!tls->priv_ssl) {
  330. ESP_LOGE(TAG, "Create wolfSSL failed");
  331. return ESP_ERR_WOLFSSL_SSL_SETUP_FAILED;
  332. }
  333. wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
  334. return ESP_OK;
  335. }
  336. int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg)
  337. {
  338. int ret;
  339. ret = wolfSSL_connect( (WOLFSSL *)tls->priv_ssl);
  340. if (ret == WOLFSSL_SUCCESS) {
  341. tls->conn_state = ESP_TLS_DONE;
  342. return 1;
  343. } else {
  344. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  345. if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE) {
  346. ESP_LOGE(TAG, "wolfSSL_connect returned %d, error code: %d", ret, err);
  347. wolfssl_print_error_msg(err);
  348. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
  349. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_WOLFSSL_SSL_HANDSHAKE_FAILED);
  350. if (cfg->crt_bundle_attach != NULL || cfg->cacert_buf != NULL || cfg->use_global_ca_store == true) {
  351. /* This is to check whether handshake failed due to invalid certificate*/
  352. esp_wolfssl_verify_certificate(tls);
  353. }
  354. tls->conn_state = ESP_TLS_FAIL;
  355. return -1;
  356. }
  357. /* Irrespective of blocking or non-blocking I/O, we return on getting wolfSSL_want_read
  358. or wolfSSL_want_write during handshake */
  359. return 0;
  360. }
  361. }
  362. ssize_t esp_wolfssl_read(esp_tls_t *tls, char *data, size_t datalen)
  363. {
  364. ssize_t ret = wolfSSL_read( (WOLFSSL *)tls->priv_ssl, (unsigned char *)data, datalen);
  365. if (ret < 0) {
  366. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  367. /* peer sent close notify */
  368. if (err == WOLFSSL_ERROR_ZERO_RETURN) {
  369. return 0;
  370. }
  371. if (ret != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE) {
  372. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, -ret);
  373. ESP_LOGE(TAG, "read error :%d:", ret);
  374. wolfssl_print_error_msg(ret);
  375. }
  376. return esp_tls_convert_wolfssl_err_to_ssize(ret);
  377. }
  378. return ret;
  379. }
  380. ssize_t esp_wolfssl_write(esp_tls_t *tls, const char *data, size_t datalen)
  381. {
  382. ssize_t ret = wolfSSL_write( (WOLFSSL *)tls->priv_ssl, (unsigned char *) data, datalen);
  383. if (ret <= 0) {
  384. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  385. if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE) {
  386. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, -err);
  387. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_WOLFSSL_SSL_WRITE_FAILED);
  388. ESP_LOGE(TAG, "write error :%d:", err);
  389. wolfssl_print_error_msg(err);
  390. }
  391. return esp_tls_convert_wolfssl_err_to_ssize(ret);
  392. }
  393. return ret;
  394. }
  395. void esp_wolfssl_verify_certificate(esp_tls_t *tls)
  396. {
  397. int flags;
  398. if ((flags = wolfSSL_get_verify_result( (WOLFSSL *)tls->priv_ssl)) != X509_V_OK) {
  399. ESP_LOGE(TAG, "Failed to verify peer certificate , returned %d", flags);
  400. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL_CERT_FLAGS, flags);
  401. } else {
  402. ESP_LOGI(TAG, "Certificate verified.");
  403. }
  404. }
  405. ssize_t esp_wolfssl_get_bytes_avail(esp_tls_t *tls)
  406. {
  407. if (!tls) {
  408. ESP_LOGE(TAG, "empty arg passed to esp_tls_get_bytes_avail()");
  409. return ESP_FAIL;
  410. }
  411. return wolfSSL_pending( (WOLFSSL *)tls->priv_ssl);
  412. }
  413. void esp_wolfssl_conn_delete(esp_tls_t *tls)
  414. {
  415. if (tls != NULL) {
  416. esp_wolfssl_cleanup(tls);
  417. }
  418. }
  419. void esp_wolfssl_cleanup(esp_tls_t *tls)
  420. {
  421. if (!tls) {
  422. return;
  423. }
  424. #ifdef CONFIG_ESP_TLS_PSK_VERIFICATION
  425. xSemaphoreGive(tls_conn_lock);
  426. #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */
  427. wolfSSL_shutdown( (WOLFSSL *)tls->priv_ssl);
  428. wolfSSL_free( (WOLFSSL *)tls->priv_ssl);
  429. tls->priv_ssl = NULL;
  430. wolfSSL_CTX_free( (WOLFSSL_CTX *)tls->priv_ctx);
  431. tls->priv_ctx = NULL;
  432. wolfSSL_Cleanup();
  433. }
  434. /**
  435. * @brief Create TLS/SSL server session
  436. */
  437. int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls)
  438. {
  439. if (tls == NULL || cfg == NULL) {
  440. return -1;
  441. }
  442. tls->role = ESP_TLS_SERVER;
  443. tls->sockfd = sockfd;
  444. esp_tls_server_params_t server_params = {};
  445. server_params.set_server_cfg = &set_server_config;
  446. esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls, &server_params);
  447. if (esp_ret != ESP_OK) {
  448. ESP_LOGE(TAG, "create_ssl_handle failed, [0x%04X] (%s)", esp_ret, esp_err_to_name(esp_ret));
  449. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret);
  450. tls->conn_state = ESP_TLS_FAIL;
  451. return -1;
  452. }
  453. tls->read = esp_wolfssl_read;
  454. tls->write = esp_wolfssl_write;
  455. int ret;
  456. while ((ret = wolfSSL_accept((WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) {
  457. int err = wolfSSL_get_error((WOLFSSL *)tls->priv_ssl, ret);
  458. if (err != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE) {
  459. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_WOLFSSL, err);
  460. ESP_LOGE(TAG, "wolfSSL_accept returned %d, error code: %d", ret, err);
  461. wolfssl_print_error_msg(err);
  462. tls->conn_state = ESP_TLS_FAIL;
  463. return -1;
  464. }
  465. }
  466. return 0;
  467. }
  468. /**
  469. * @brief Close the server side TLS/SSL connection and free any allocated resources.
  470. */
  471. void esp_wolfssl_server_session_delete(esp_tls_t *tls)
  472. {
  473. if (tls != NULL) {
  474. esp_wolfssl_cleanup(tls);
  475. esp_tls_internal_event_tracker_destroy(tls->error_handle);
  476. free(tls);
  477. }
  478. }
  479. esp_err_t esp_wolfssl_init_global_ca_store(void)
  480. {
  481. /* This function is just to provide consistancy between function calls of esp_tls.h and wolfssl */
  482. return ESP_OK;
  483. }
  484. esp_err_t esp_wolfssl_set_global_ca_store(const unsigned char *cacert_pem_buf, const unsigned int cacert_pem_bytes)
  485. {
  486. if (cacert_pem_buf == NULL) {
  487. ESP_LOGE(TAG, "cacert_pem_buf is null");
  488. return ESP_ERR_INVALID_ARG;
  489. }
  490. if (global_cacert != NULL) {
  491. esp_wolfssl_free_global_ca_store();
  492. }
  493. global_cacert = (unsigned char *)strndup((const char *)cacert_pem_buf, cacert_pem_bytes);
  494. if (!global_cacert) {
  495. return ESP_FAIL;
  496. }
  497. global_cacert_pem_bytes = cacert_pem_bytes;
  498. return ESP_OK;
  499. }
  500. void esp_wolfssl_free_global_ca_store(void)
  501. {
  502. if (global_cacert) {
  503. free(global_cacert);
  504. global_cacert = NULL;
  505. global_cacert_pem_bytes = 0;
  506. }
  507. }
  508. #if defined(CONFIG_ESP_TLS_PSK_VERIFICATION)
  509. static esp_err_t esp_wolfssl_set_cipher_list(WOLFSSL_CTX *ctx)
  510. {
  511. const char *defaultCipherList;
  512. int ret;
  513. #if defined(HAVE_AESGCM) && !defined(NO_DH)
  514. #ifdef WOLFSSL_TLS13
  515. defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:"
  516. "TLS13-AES128-GCM-SHA256";
  517. #else
  518. defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
  519. #endif
  520. #elif defined(HAVE_NULL_CIPHER)
  521. defaultCipherList = "PSK-NULL-SHA256";
  522. #else
  523. defaultCipherList = "PSK-AES128-CBC-SHA256";
  524. #endif
  525. ESP_LOGD(TAG, "cipher list is %s", defaultCipherList);
  526. if ((ret = wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)) != WOLFSSL_SUCCESS) {
  527. wolfSSL_CTX_free(ctx);
  528. int err = wolfSSL_get_error( (WOLFSSL *)tls->priv_ssl, ret);
  529. ESP_LOGE(TAG, "can't set cipher list, returned %d, error code: %d", ret, err);
  530. wolfssl_print_error_msg(err);
  531. return ESP_FAIL;
  532. }
  533. return ESP_OK;
  534. }
  535. /* initialize the mutex before app_main() when using PSK */
  536. static void __attribute__((constructor))
  537. espt_tls_wolfssl_init_conn_lock (void)
  538. {
  539. if ((tls_conn_lock = xSemaphoreCreateMutex()) == NULL) {
  540. ESP_EARLY_LOGE(TAG, "mutex for tls psk connection could not be created");
  541. }
  542. }
  543. /* Some callback functions required by PSK */
  544. static inline unsigned int esp_wolfssl_psk_client_cb(WOLFSSL* ssl, const char* hint,
  545. char* identity, unsigned int id_max_len, unsigned char* key,
  546. unsigned int key_max_len)
  547. {
  548. (void)key_max_len;
  549. /* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
  550. memcpy(identity, psk_id_str, id_max_len);
  551. for(int count = 0; count < psk_key_max_len; count ++) {
  552. key[count] = psk_key_array[count];
  553. }
  554. xSemaphoreGive(tls_conn_lock);
  555. return psk_key_max_len;
  556. /* return length of key in octets or 0 or for error */
  557. }
  558. #endif /* CONFIG_ESP_TLS_PSK_VERIFICATION */