esp_tls.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  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 "sdkconfig.h"
  15. #include "esp_tls.h"
  16. #include "esp_tls_private.h"
  17. #include "esp_tls_error_capture_internal.h"
  18. #include <fcntl.h>
  19. #include <errno.h>
  20. #if CONFIG_IDF_TARGET_LINUX && !ESP_TLS_WITH_LWIP
  21. #include <arpa/inet.h>
  22. #include <netinet/in.h>
  23. #include <netinet/tcp.h>
  24. #include <linux/if.h>
  25. #include <sys/time.h>
  26. typedef struct in_addr ip_addr_t;
  27. typedef struct in6_addr ip6_addr_t;
  28. #define ipaddr_ntoa(ipaddr) inet_ntoa(*ipaddr)
  29. static inline char *ip6addr_ntoa(const ip6_addr_t *addr)
  30. {
  31. static char str[40];
  32. return (char *)inet_ntop(AF_INET6, addr->s6_addr, str, 40);
  33. }
  34. #endif // CONFIG_IDF_TARGET_LINUX && !ESP_TLS_WITH_LWIP
  35. static const char *TAG = "esp-tls";
  36. #ifdef CONFIG_ESP_TLS_USING_MBEDTLS
  37. #include "esp_tls_mbedtls.h"
  38. #elif CONFIG_ESP_TLS_USING_WOLFSSL
  39. #include "esp_tls_wolfssl.h"
  40. #endif
  41. #ifdef ESP_PLATFORM
  42. #include <esp_log.h>
  43. #else
  44. #define ESP_LOGD(TAG, ...) //printf(__VA_ARGS__);
  45. #define ESP_LOGE(TAG, ...) printf(__VA_ARGS__);
  46. #endif
  47. #ifdef CONFIG_ESP_TLS_USING_MBEDTLS
  48. #define _esp_create_ssl_handle esp_create_mbedtls_handle
  49. #define _esp_tls_handshake esp_mbedtls_handshake
  50. #define _esp_tls_read esp_mbedtls_read
  51. #define _esp_tls_write esp_mbedtls_write
  52. #define _esp_tls_conn_delete esp_mbedtls_conn_delete
  53. #define _esp_tls_net_init esp_mbedtls_net_init
  54. #define _esp_tls_get_client_session esp_mbedtls_get_client_session
  55. #define _esp_tls_free_client_session esp_mbedtls_free_client_session
  56. #define _esp_tls_get_ssl_context esp_mbedtls_get_ssl_context
  57. #define _esp_tls_server_session_create esp_mbedtls_server_session_create
  58. #define _esp_tls_server_session_delete esp_mbedtls_server_session_delete
  59. #define _esp_tls_server_session_ticket_ctx_init esp_mbedtls_server_session_ticket_ctx_init
  60. #define _esp_tls_server_session_ticket_ctx_free esp_mbedtls_server_session_ticket_ctx_free
  61. #define _esp_tls_get_bytes_avail esp_mbedtls_get_bytes_avail
  62. #define _esp_tls_init_global_ca_store esp_mbedtls_init_global_ca_store
  63. #define _esp_tls_set_global_ca_store esp_mbedtls_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */
  64. #define _esp_tls_get_global_ca_store esp_mbedtls_get_global_ca_store
  65. #define _esp_tls_free_global_ca_store esp_mbedtls_free_global_ca_store /*!< Callback function for freeing global ca store for TLS/SSL */
  66. #define _esp_tls_get_ciphersuites_list esp_mbedtls_get_ciphersuites_list
  67. #elif CONFIG_ESP_TLS_USING_WOLFSSL /* CONFIG_ESP_TLS_USING_MBEDTLS */
  68. #define _esp_create_ssl_handle esp_create_wolfssl_handle
  69. #define _esp_tls_handshake esp_wolfssl_handshake
  70. #define _esp_tls_read esp_wolfssl_read
  71. #define _esp_tls_write esp_wolfssl_write
  72. #define _esp_tls_conn_delete esp_wolfssl_conn_delete
  73. #define _esp_tls_net_init esp_wolfssl_net_init
  74. #define _esp_tls_server_session_create esp_wolfssl_server_session_create
  75. #define _esp_tls_server_session_delete esp_wolfssl_server_session_delete
  76. #define _esp_tls_get_bytes_avail esp_wolfssl_get_bytes_avail
  77. #define _esp_tls_init_global_ca_store esp_wolfssl_init_global_ca_store
  78. #define _esp_tls_set_global_ca_store esp_wolfssl_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */
  79. #define _esp_tls_free_global_ca_store esp_wolfssl_free_global_ca_store /*!< Callback function for freeing global ca store for TLS/SSL */
  80. #define _esp_tls_get_ssl_context esp_wolfssl_get_ssl_context
  81. #else /* ESP_TLS_USING_WOLFSSL */
  82. #error "No TLS stack configured"
  83. #endif
  84. #if CONFIG_IDF_TARGET_LINUX
  85. #define IPV4_ENABLED 1
  86. #define IPV6_ENABLED 1
  87. #else // CONFIG_IDF_TARGET_LINUX
  88. #define IPV4_ENABLED CONFIG_LWIP_IPV4
  89. #define IPV6_ENABLED CONFIG_LWIP_IPV6
  90. #endif // !CONFIG_IDF_TARGET_LINUX
  91. #define ESP_TLS_DEFAULT_CONN_TIMEOUT (10) /*!< Default connection timeout in seconds */
  92. static esp_err_t create_ssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls)
  93. {
  94. return _esp_create_ssl_handle(hostname, hostlen, cfg, tls, NULL);
  95. }
  96. static esp_err_t esp_tls_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg)
  97. {
  98. return _esp_tls_handshake(tls, cfg);
  99. }
  100. static ssize_t tcp_read(esp_tls_t *tls, char *data, size_t datalen)
  101. {
  102. return recv(tls->sockfd, data, datalen, 0);
  103. }
  104. static ssize_t tcp_write(esp_tls_t *tls, const char *data, size_t datalen)
  105. {
  106. return send(tls->sockfd, data, datalen, 0);
  107. }
  108. ssize_t esp_tls_conn_read(esp_tls_t *tls, void *data, size_t datalen)
  109. {
  110. return tls->read(tls, (char *)data, datalen);
  111. }
  112. ssize_t esp_tls_conn_write(esp_tls_t *tls, const void *data, size_t datalen)
  113. {
  114. return tls->write(tls, (char *)data, datalen);
  115. }
  116. /**
  117. * @brief Close the TLS connection and free any allocated resources.
  118. */
  119. int esp_tls_conn_destroy(esp_tls_t *tls)
  120. {
  121. if (tls != NULL) {
  122. int ret = 0;
  123. _esp_tls_conn_delete(tls);
  124. if (tls->sockfd >= 0) {
  125. ret = close(tls->sockfd);
  126. }
  127. esp_tls_internal_event_tracker_destroy(tls->error_handle);
  128. free(tls);
  129. return ret;
  130. }
  131. return -1; // invalid argument
  132. }
  133. esp_tls_t *esp_tls_init(void)
  134. {
  135. esp_tls_t *tls = (esp_tls_t *)calloc(1, sizeof(esp_tls_t));
  136. if (!tls) {
  137. return NULL;
  138. }
  139. tls->error_handle = esp_tls_internal_event_tracker_create();
  140. if (!tls->error_handle) {
  141. free(tls);
  142. return NULL;
  143. }
  144. _esp_tls_net_init(tls);
  145. tls->sockfd = -1;
  146. return tls;
  147. }
  148. static esp_err_t esp_tls_hostname_to_fd(const char *host, size_t hostlen, int port, esp_tls_addr_family_t addr_family, struct sockaddr_storage *address, int* fd)
  149. {
  150. struct addrinfo *address_info;
  151. struct addrinfo hints;
  152. memset(&hints, 0, sizeof(hints));
  153. switch (addr_family) {
  154. case ESP_TLS_AF_INET:
  155. hints.ai_family = AF_INET;
  156. break;
  157. case ESP_TLS_AF_INET6:
  158. hints.ai_family = AF_INET6;
  159. break;
  160. default:
  161. hints.ai_family = AF_UNSPEC;
  162. break;
  163. }
  164. hints.ai_socktype = SOCK_STREAM;
  165. char *use_host = strndup(host, hostlen);
  166. if (!use_host) {
  167. return ESP_ERR_NO_MEM;
  168. }
  169. ESP_LOGD(TAG, "host:%s: strlen %lu", use_host, (unsigned long)hostlen);
  170. int res = getaddrinfo(use_host, NULL, &hints, &address_info);
  171. if (res != 0 || address_info == NULL) {
  172. ESP_LOGE(TAG, "couldn't get hostname for :%s: "
  173. "getaddrinfo() returns %d, addrinfo=%p", use_host, res, address_info);
  174. free(use_host);
  175. return ESP_ERR_ESP_TLS_CANNOT_RESOLVE_HOSTNAME;
  176. }
  177. free(use_host);
  178. *fd = socket(address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol);
  179. if (*fd < 0) {
  180. ESP_LOGE(TAG, "Failed to create socket (family %d socktype %d protocol %d)", address_info->ai_family, address_info->ai_socktype, address_info->ai_protocol);
  181. freeaddrinfo(address_info);
  182. return ESP_ERR_ESP_TLS_CANNOT_CREATE_SOCKET;
  183. }
  184. #if IPV4_ENABLED
  185. if (address_info->ai_family == AF_INET) {
  186. struct sockaddr_in *p = (struct sockaddr_in *)address_info->ai_addr;
  187. p->sin_port = htons(port);
  188. ESP_LOGD(TAG, "[sock=%d] Resolved IPv4 address: %s", *fd, ipaddr_ntoa((const ip_addr_t*)&p->sin_addr.s_addr));
  189. memcpy(address, p, sizeof(struct sockaddr ));
  190. }
  191. #endif
  192. #if IPV4_ENABLED && IPV6_ENABLED
  193. else
  194. #endif
  195. #if IPV6_ENABLED
  196. if (address_info->ai_family == AF_INET6) {
  197. struct sockaddr_in6 *p = (struct sockaddr_in6 *)address_info->ai_addr;
  198. p->sin6_port = htons(port);
  199. p->sin6_family = AF_INET6;
  200. ESP_LOGD(TAG, "[sock=%d] Resolved IPv6 address: %s", *fd, ip6addr_ntoa((const ip6_addr_t*)&p->sin6_addr));
  201. memcpy(address, p, sizeof(struct sockaddr_in6 ));
  202. }
  203. #endif
  204. else {
  205. ESP_LOGE(TAG, "Unsupported protocol family %d", address_info->ai_family);
  206. close(*fd);
  207. freeaddrinfo(address_info);
  208. return ESP_ERR_ESP_TLS_UNSUPPORTED_PROTOCOL_FAMILY;
  209. }
  210. freeaddrinfo(address_info);
  211. return ESP_OK;
  212. }
  213. static void ms_to_timeval(int timeout_ms, struct timeval *tv)
  214. {
  215. tv->tv_sec = timeout_ms / 1000;
  216. tv->tv_usec = (timeout_ms % 1000) * 1000;
  217. }
  218. static esp_err_t esp_tls_set_socket_options(int fd, const esp_tls_cfg_t *cfg)
  219. {
  220. if (cfg) {
  221. struct timeval tv = {};
  222. if (cfg->timeout_ms > 0) {
  223. ms_to_timeval(cfg->timeout_ms, &tv);
  224. } else {
  225. tv.tv_sec = ESP_TLS_DEFAULT_CONN_TIMEOUT;
  226. tv.tv_usec = 0;
  227. }
  228. if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0) {
  229. ESP_LOGE(TAG, "Fail to setsockopt SO_RCVTIMEO");
  230. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  231. }
  232. if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) != 0) {
  233. ESP_LOGE(TAG, "Fail to setsockopt SO_SNDTIMEO");
  234. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  235. }
  236. if (cfg->keep_alive_cfg && cfg->keep_alive_cfg->keep_alive_enable) {
  237. int keep_alive_enable = 1;
  238. int keep_alive_idle = cfg->keep_alive_cfg->keep_alive_idle;
  239. int keep_alive_interval = cfg->keep_alive_cfg->keep_alive_interval;
  240. int keep_alive_count = cfg->keep_alive_cfg->keep_alive_count;
  241. ESP_LOGD(TAG, "Enable TCP keep alive. idle: %d, interval: %d, count: %d", keep_alive_idle, keep_alive_interval, keep_alive_count);
  242. if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive_enable, sizeof(keep_alive_enable)) != 0) {
  243. ESP_LOGE(TAG, "Fail to setsockopt SO_KEEPALIVE");
  244. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  245. }
  246. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_alive_idle, sizeof(keep_alive_idle)) != 0) {
  247. ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPIDLE");
  248. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  249. }
  250. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_alive_interval, sizeof(keep_alive_interval)) != 0) {
  251. ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPINTVL");
  252. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  253. }
  254. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_alive_count, sizeof(keep_alive_count)) != 0) {
  255. ESP_LOGE(TAG, "Fail to setsockopt TCP_KEEPCNT");
  256. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  257. }
  258. }
  259. if (cfg->if_name) {
  260. if (cfg->if_name->ifr_name[0] != 0) {
  261. ESP_LOGD(TAG, "Bind [sock=%d] to interface %s", fd, cfg->if_name->ifr_name);
  262. if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, cfg->if_name, sizeof(struct ifreq)) != 0) {
  263. ESP_LOGE(TAG, "Bind [sock=%d] to interface %s fail", fd, cfg->if_name->ifr_name);
  264. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  265. }
  266. }
  267. }
  268. }
  269. return ESP_OK;
  270. }
  271. static esp_err_t esp_tls_set_socket_non_blocking(int fd, bool non_blocking)
  272. {
  273. int flags;
  274. if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
  275. ESP_LOGE(TAG, "[sock=%d] get file flags error: %s", fd, strerror(errno));
  276. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  277. }
  278. if (non_blocking) {
  279. flags |= O_NONBLOCK;
  280. } else {
  281. flags &= ~O_NONBLOCK;
  282. }
  283. if (fcntl(fd, F_SETFL, flags) < 0) {
  284. ESP_LOGE(TAG, "[sock=%d] set blocking/nonblocking error: %s", fd, strerror(errno));
  285. return ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  286. }
  287. return ESP_OK;
  288. }
  289. static inline esp_err_t tcp_connect(const char *host, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_error_handle_t error_handle, int *sockfd)
  290. {
  291. struct sockaddr_storage address;
  292. int fd;
  293. esp_tls_addr_family_t addr_family = (cfg != NULL) ? cfg->addr_family : ESP_TLS_AF_UNSPEC;
  294. esp_err_t ret = esp_tls_hostname_to_fd(host, hostlen, port, addr_family, &address, &fd);
  295. if (ret != ESP_OK) {
  296. ESP_INT_EVENT_TRACKER_CAPTURE(error_handle, ESP_TLS_ERR_TYPE_SYSTEM, errno);
  297. return ret;
  298. }
  299. // Set timeout options, keep-alive options and bind device options if configured
  300. ret = esp_tls_set_socket_options(fd, cfg);
  301. if (ret != ESP_OK) {
  302. goto err;
  303. }
  304. // Set to non block before connecting to better control connection timeout
  305. ret = esp_tls_set_socket_non_blocking(fd, true);
  306. if (ret != ESP_OK) {
  307. goto err;
  308. }
  309. ret = ESP_ERR_ESP_TLS_FAILED_CONNECT_TO_HOST;
  310. ESP_LOGD(TAG, "[sock=%d] Connecting to server. HOST: %s, Port: %d", fd, host, port);
  311. if (connect(fd, (struct sockaddr *)&address, sizeof(struct sockaddr)) < 0) {
  312. if (errno == EINPROGRESS) {
  313. fd_set fdset;
  314. struct timeval tv = { .tv_usec = 0, .tv_sec = ESP_TLS_DEFAULT_CONN_TIMEOUT }; // Default connection timeout is 10 s
  315. if (cfg && cfg->non_block) {
  316. // Non-blocking mode -> just return successfully at this stage
  317. *sockfd = fd;
  318. return ESP_OK;
  319. }
  320. if ( cfg && cfg->timeout_ms > 0 ) {
  321. ms_to_timeval(cfg->timeout_ms, &tv);
  322. }
  323. FD_ZERO(&fdset);
  324. FD_SET(fd, &fdset);
  325. int res = select(fd+1, NULL, &fdset, NULL, &tv);
  326. if (res < 0) {
  327. ESP_LOGE(TAG, "[sock=%d] select() error: %s", fd, strerror(errno));
  328. ESP_INT_EVENT_TRACKER_CAPTURE(error_handle, ESP_TLS_ERR_TYPE_SYSTEM, errno);
  329. goto err;
  330. }
  331. else if (res == 0) {
  332. ESP_LOGE(TAG, "[sock=%d] select() timeout", fd);
  333. ret = ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT;
  334. goto err;
  335. } else {
  336. int sockerr;
  337. socklen_t len = (socklen_t)sizeof(int);
  338. if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)(&sockerr), &len) < 0) {
  339. ESP_LOGE(TAG, "[sock=%d] getsockopt() error: %s", fd, strerror(errno));
  340. ret = ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED;
  341. goto err;
  342. }
  343. else if (sockerr) {
  344. ESP_INT_EVENT_TRACKER_CAPTURE(error_handle, ESP_TLS_ERR_TYPE_SYSTEM, sockerr);
  345. ESP_LOGE(TAG, "[sock=%d] delayed connect error: %s", fd, strerror(sockerr));
  346. goto err;
  347. }
  348. }
  349. } else {
  350. ESP_LOGE(TAG, "[sock=%d] connect() error: %s", fd, strerror(errno));
  351. goto err;
  352. }
  353. }
  354. if (cfg && cfg->non_block == false) {
  355. // reset back to blocking mode (unless non_block configured)
  356. ret = esp_tls_set_socket_non_blocking(fd, false);
  357. if (ret != ESP_OK) {
  358. goto err;
  359. }
  360. }
  361. *sockfd = fd;
  362. return ESP_OK;
  363. err:
  364. close(fd);
  365. return ret;
  366. }
  367. static int esp_tls_low_level_conn(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls)
  368. {
  369. if (!tls) {
  370. ESP_LOGE(TAG, "empty esp_tls parameter");
  371. return -1;
  372. }
  373. esp_err_t esp_ret;
  374. /* These states are used to keep a tab on connection progress in case of non-blocking connect,
  375. and in case of blocking connect these cases will get executed one after the other */
  376. switch (tls->conn_state) {
  377. case ESP_TLS_INIT:
  378. tls->sockfd = -1;
  379. if (cfg != NULL && cfg->is_plain_tcp == false) {
  380. _esp_tls_net_init(tls);
  381. tls->is_tls = true;
  382. }
  383. if ((esp_ret = tcp_connect(hostname, hostlen, port, cfg, tls->error_handle, &tls->sockfd)) != ESP_OK) {
  384. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret);
  385. return -1;
  386. }
  387. if (tls->is_tls == false) {
  388. tls->read = tcp_read;
  389. tls->write = tcp_write;
  390. ESP_LOGD(TAG, "non-tls connection established");
  391. return 1;
  392. }
  393. if (cfg && cfg->non_block) {
  394. FD_ZERO(&tls->rset);
  395. FD_SET(tls->sockfd, &tls->rset);
  396. tls->wset = tls->rset;
  397. }
  398. tls->conn_state = ESP_TLS_CONNECTING;
  399. /* falls through */
  400. case ESP_TLS_CONNECTING:
  401. if (cfg && cfg->non_block) {
  402. ESP_LOGD(TAG, "connecting...");
  403. struct timeval tv;
  404. ms_to_timeval(cfg->timeout_ms, &tv);
  405. /* In case of non-blocking I/O, we use the select() API to check whether
  406. connection has been established or not*/
  407. if (select(tls->sockfd + 1, &tls->rset, &tls->wset, NULL,
  408. cfg->timeout_ms>0 ? &tv : NULL) == 0) {
  409. ESP_LOGD(TAG, "select() timed out");
  410. return 0;
  411. }
  412. if (FD_ISSET(tls->sockfd, &tls->rset) || FD_ISSET(tls->sockfd, &tls->wset)) {
  413. int error;
  414. socklen_t len = sizeof(error);
  415. /* pending error check */
  416. if (getsockopt(tls->sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
  417. ESP_LOGD(TAG, "Non blocking connect failed");
  418. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_SYSTEM, errno);
  419. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_ESP_TLS_SOCKET_SETOPT_FAILED);
  420. tls->conn_state = ESP_TLS_FAIL;
  421. return -1;
  422. }
  423. }
  424. }
  425. /* By now, the connection has been established */
  426. esp_ret = create_ssl_handle(hostname, hostlen, cfg, tls);
  427. if (esp_ret != ESP_OK) {
  428. ESP_LOGE(TAG, "create_ssl_handle failed");
  429. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, esp_ret);
  430. tls->conn_state = ESP_TLS_FAIL;
  431. return -1;
  432. }
  433. tls->read = _esp_tls_read;
  434. tls->write = _esp_tls_write;
  435. tls->conn_state = ESP_TLS_HANDSHAKE;
  436. /* falls through */
  437. case ESP_TLS_HANDSHAKE:
  438. ESP_LOGD(TAG, "handshake in progress...");
  439. return esp_tls_handshake(tls, cfg);
  440. break;
  441. case ESP_TLS_FAIL:
  442. ESP_LOGE(TAG, "failed to open a new connection");;
  443. break;
  444. default:
  445. ESP_LOGE(TAG, "invalid esp-tls state");
  446. break;
  447. }
  448. return -1;
  449. }
  450. /**
  451. * @brief Create a new plain TCP connection
  452. */
  453. esp_err_t esp_tls_plain_tcp_connect(const char *host, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_error_handle_t error_handle, int *sockfd)
  454. {
  455. if (sockfd == NULL || error_handle == NULL) {
  456. return ESP_ERR_INVALID_ARG;
  457. }
  458. return tcp_connect(host, hostlen, port, cfg, error_handle, sockfd);
  459. }
  460. int esp_tls_conn_new_sync(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls)
  461. {
  462. struct timeval time = {};
  463. gettimeofday(&time, NULL);
  464. uint32_t start_time_ms = (time.tv_sec * 1000) + (time.tv_usec / 1000);
  465. while (1) {
  466. int ret = esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls);
  467. if (ret == 1) {
  468. return ret;
  469. } else if (ret == -1) {
  470. ESP_LOGE(TAG, "Failed to open new connection");
  471. return -1;
  472. } else if (ret == 0 && cfg->timeout_ms >= 0) {
  473. gettimeofday(&time, NULL);
  474. uint32_t current_time_ms = (time.tv_sec * 1000) + (time.tv_usec / 1000);
  475. uint32_t elapsed_time_ms = current_time_ms - start_time_ms;
  476. if (elapsed_time_ms >= cfg->timeout_ms) {
  477. ESP_LOGW(TAG, "Failed to open new connection in specified timeout");
  478. ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ESP_TLS_ERR_TYPE_ESP, ESP_ERR_ESP_TLS_CONNECTION_TIMEOUT);
  479. return 0;
  480. }
  481. }
  482. }
  483. return 0;
  484. }
  485. /*
  486. * @brief Create a new TLS/SSL non-blocking connection
  487. */
  488. int esp_tls_conn_new_async(const char *hostname, int hostlen, int port, const esp_tls_cfg_t *cfg, esp_tls_t *tls)
  489. {
  490. return esp_tls_low_level_conn(hostname, hostlen, port, cfg, tls);
  491. }
  492. static int get_port(const char *url, struct http_parser_url *u)
  493. {
  494. if (u->field_data[UF_PORT].len) {
  495. return strtol(&url[u->field_data[UF_PORT].off], NULL, 10);
  496. } else {
  497. if (strncasecmp(&url[u->field_data[UF_SCHEMA].off], "http", u->field_data[UF_SCHEMA].len) == 0) {
  498. return 80;
  499. } else if (strncasecmp(&url[u->field_data[UF_SCHEMA].off], "https", u->field_data[UF_SCHEMA].len) == 0) {
  500. return 443;
  501. }
  502. }
  503. return 0;
  504. }
  505. esp_tls_t *esp_tls_conn_http_new(const char *url, const esp_tls_cfg_t *cfg)
  506. {
  507. /* Parse URI */
  508. struct http_parser_url u;
  509. http_parser_url_init(&u);
  510. http_parser_parse_url(url, strlen(url), 0, &u);
  511. esp_tls_t *tls = esp_tls_init();
  512. if (!tls) {
  513. return NULL;
  514. }
  515. /* Connect to host */
  516. if (esp_tls_conn_new_sync(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len,
  517. get_port(url, &u), cfg, tls) == 1) {
  518. return tls;
  519. }
  520. esp_tls_conn_destroy(tls);
  521. return NULL;
  522. }
  523. /**
  524. * @brief Create a new TLS/SSL connection with a given "HTTP" url
  525. */
  526. int esp_tls_conn_http_new_sync(const char *url, const esp_tls_cfg_t *cfg, esp_tls_t *tls)
  527. {
  528. /* Parse URI */
  529. struct http_parser_url u;
  530. http_parser_url_init(&u);
  531. http_parser_parse_url(url, strlen(url), 0, &u);
  532. /* Connect to host */
  533. return esp_tls_conn_new_sync(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len,
  534. get_port(url, &u), cfg, tls);
  535. }
  536. /**
  537. * @brief Create a new non-blocking TLS/SSL connection with a given "HTTP" url
  538. */
  539. int esp_tls_conn_http_new_async(const char *url, const esp_tls_cfg_t *cfg, esp_tls_t *tls)
  540. {
  541. /* Parse URI */
  542. struct http_parser_url u;
  543. http_parser_url_init(&u);
  544. http_parser_parse_url(url, strlen(url), 0, &u);
  545. /* Connect to host */
  546. return esp_tls_conn_new_async(&url[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len,
  547. get_port(url, &u), cfg, tls);
  548. }
  549. #ifdef CONFIG_ESP_TLS_USING_MBEDTLS
  550. mbedtls_x509_crt *esp_tls_get_global_ca_store(void)
  551. {
  552. return _esp_tls_get_global_ca_store();
  553. }
  554. const int *esp_tls_get_ciphersuites_list(void)
  555. {
  556. return _esp_tls_get_ciphersuites_list();
  557. }
  558. #endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
  559. #ifdef CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS
  560. esp_tls_client_session_t *esp_tls_get_client_session(esp_tls_t *tls)
  561. {
  562. return _esp_tls_get_client_session(tls);
  563. }
  564. void esp_tls_free_client_session(esp_tls_client_session_t *client_session)
  565. {
  566. _esp_tls_free_client_session(client_session);
  567. }
  568. #endif /* CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS */
  569. esp_err_t esp_tls_cfg_server_session_tickets_init(esp_tls_cfg_server_t *cfg)
  570. {
  571. #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)
  572. if (!cfg || cfg->ticket_ctx) {
  573. return ESP_ERR_INVALID_ARG;
  574. }
  575. cfg->ticket_ctx = calloc(1, sizeof(esp_tls_server_session_ticket_ctx_t));
  576. if (!cfg->ticket_ctx) {
  577. return ESP_ERR_NO_MEM;
  578. }
  579. esp_err_t ret = _esp_tls_server_session_ticket_ctx_init(cfg->ticket_ctx);
  580. if (ret != ESP_OK) {
  581. free(cfg->ticket_ctx);
  582. }
  583. return ret;
  584. #else
  585. return ESP_ERR_NOT_SUPPORTED;
  586. #endif
  587. }
  588. void esp_tls_cfg_server_session_tickets_free(esp_tls_cfg_server_t *cfg)
  589. {
  590. #if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)
  591. if (cfg && cfg->ticket_ctx) {
  592. _esp_tls_server_session_ticket_ctx_free(cfg->ticket_ctx);
  593. }
  594. #endif
  595. }
  596. /**
  597. * @brief Create a server side TLS/SSL connection
  598. */
  599. int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls)
  600. {
  601. return _esp_tls_server_session_create(cfg, sockfd, tls);
  602. }
  603. /**
  604. * @brief Close the server side TLS/SSL connection and free any allocated resources.
  605. */
  606. void esp_tls_server_session_delete(esp_tls_t *tls)
  607. {
  608. return _esp_tls_server_session_delete(tls);
  609. }
  610. ssize_t esp_tls_get_bytes_avail(esp_tls_t *tls)
  611. {
  612. return _esp_tls_get_bytes_avail(tls);
  613. }
  614. void *esp_tls_get_ssl_context(esp_tls_t *tls)
  615. {
  616. return _esp_tls_get_ssl_context(tls);
  617. }
  618. esp_err_t esp_tls_get_conn_sockfd(esp_tls_t *tls, int *sockfd)
  619. {
  620. if (!tls || !sockfd) {
  621. ESP_LOGE(TAG, "Invalid arguments passed");
  622. return ESP_ERR_INVALID_ARG;
  623. }
  624. *sockfd = tls->sockfd;
  625. return ESP_OK;
  626. }
  627. esp_err_t esp_tls_set_conn_sockfd(esp_tls_t *tls, int sockfd)
  628. {
  629. if (!tls || sockfd < 0) {
  630. ESP_LOGE(TAG, "Invalid arguments passed");
  631. return ESP_ERR_INVALID_ARG;
  632. }
  633. tls->sockfd = sockfd;
  634. return ESP_OK;
  635. }
  636. esp_err_t esp_tls_get_conn_state(esp_tls_t *tls, esp_tls_conn_state_t *conn_state)
  637. {
  638. if (!tls || !conn_state) {
  639. ESP_LOGE(TAG, "Invalid arguments passed");
  640. return ESP_ERR_INVALID_ARG;
  641. }
  642. *conn_state = tls->conn_state;
  643. return ESP_OK;
  644. }
  645. esp_err_t esp_tls_set_conn_state(esp_tls_t *tls, esp_tls_conn_state_t conn_state)
  646. {
  647. if (!tls || conn_state < ESP_TLS_INIT || conn_state > ESP_TLS_DONE) {
  648. ESP_LOGE(TAG, "Invalid arguments passed");
  649. return ESP_ERR_INVALID_ARG;
  650. }
  651. tls->conn_state = conn_state;
  652. return ESP_OK;
  653. }
  654. esp_err_t esp_tls_get_and_clear_last_error(esp_tls_error_handle_t h, int *esp_tls_code, int *esp_tls_flags)
  655. {
  656. if (!h) {
  657. return ESP_ERR_INVALID_STATE;
  658. }
  659. esp_err_t last_err = h->last_error;
  660. if (esp_tls_code) {
  661. *esp_tls_code = h->esp_tls_error_code;
  662. }
  663. if (esp_tls_flags) {
  664. *esp_tls_flags = h->esp_tls_flags;
  665. }
  666. memset(h, 0, sizeof(esp_tls_last_error_t));
  667. return last_err;
  668. }
  669. esp_err_t esp_tls_get_error_handle(esp_tls_t *tls, esp_tls_error_handle_t *error_handle)
  670. {
  671. if (!tls || !error_handle) {
  672. return ESP_ERR_INVALID_ARG;
  673. }
  674. *error_handle = tls->error_handle;
  675. return ESP_OK;
  676. }
  677. esp_err_t esp_tls_init_global_ca_store(void)
  678. {
  679. return _esp_tls_init_global_ca_store();
  680. }
  681. esp_err_t esp_tls_set_global_ca_store(const unsigned char *cacert_pem_buf, const unsigned int cacert_pem_bytes)
  682. {
  683. return _esp_tls_set_global_ca_store(cacert_pem_buf, cacert_pem_bytes);
  684. }
  685. void esp_tls_free_global_ca_store(void)
  686. {
  687. return _esp_tls_free_global_ca_store();
  688. }