esp_tls_wolfssl.c 21 KB

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