2022-02-03 07:45:11 -05:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
2017-11-13 22:16:20 -05:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2018-07-27 08:48:26 -04:00
|
|
|
#include "esp_tls.h"
|
2017-11-13 22:16:20 -05:00
|
|
|
#include "esp_log.h"
|
|
|
|
|
2018-09-25 04:34:04 -04:00
|
|
|
#include "esp_transport.h"
|
|
|
|
#include "esp_transport_ssl.h"
|
|
|
|
#include "esp_transport_utils.h"
|
2020-07-17 11:59:05 -04:00
|
|
|
#include "esp_transport_internal.h"
|
2017-11-13 22:16:20 -05:00
|
|
|
|
2021-05-19 06:45:24 -04:00
|
|
|
#define INVALID_SOCKET (-1)
|
|
|
|
|
2021-02-04 04:18:56 -05:00
|
|
|
#define GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t) \
|
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t); \
|
|
|
|
if (!ssl) { return; }
|
|
|
|
|
2021-01-25 03:45:38 -05:00
|
|
|
static const char *TAG = "TRANSPORT_BASE";
|
2018-08-07 13:56:59 -04:00
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
TRANS_SSL_INIT = 0,
|
|
|
|
TRANS_SSL_CONNECTING,
|
|
|
|
} transport_ssl_conn_state_t;
|
|
|
|
|
2017-11-13 22:16:20 -05:00
|
|
|
/**
|
|
|
|
* mbedtls specific transport data
|
|
|
|
*/
|
2021-01-23 03:46:06 -05:00
|
|
|
typedef struct transport_esp_tls {
|
2018-07-27 08:48:26 -04:00
|
|
|
esp_tls_t *tls;
|
2018-08-07 13:56:59 -04:00
|
|
|
esp_tls_cfg_t cfg;
|
2017-11-13 22:16:20 -05:00
|
|
|
bool ssl_initialized;
|
2018-08-07 13:56:59 -04:00
|
|
|
transport_ssl_conn_state_t conn_state;
|
2021-05-04 04:23:52 -04:00
|
|
|
int sockfd;
|
2021-01-25 03:45:38 -05:00
|
|
|
} transport_esp_tls_t;
|
2017-11-13 22:16:20 -05:00
|
|
|
|
2021-02-04 04:18:56 -05:00
|
|
|
static inline struct transport_esp_tls * ssl_get_context_data(esp_transport_handle_t t)
|
|
|
|
{
|
|
|
|
if (!t) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (t->data) { // Prefer internal ssl context (independent from the list)
|
|
|
|
return (transport_esp_tls_t*)t->data;
|
|
|
|
}
|
|
|
|
if (t->base && t->base->transport_esp_tls) { // Next one is the lists inherent context
|
|
|
|
t->data = t->base->transport_esp_tls; // Optimize: if we have base context, use it as internal
|
|
|
|
return t->base->transport_esp_tls;
|
|
|
|
}
|
|
|
|
// If we don't have a valid context, let's to create one
|
|
|
|
transport_esp_tls_t *ssl = esp_transport_esp_tls_create();
|
|
|
|
ESP_TRANSPORT_MEM_CHECK(TAG, ssl, return NULL)
|
|
|
|
t->data = ssl;
|
|
|
|
return ssl;
|
|
|
|
}
|
|
|
|
|
2021-01-25 03:45:38 -05:00
|
|
|
static int esp_tls_connect_async(esp_transport_handle_t t, const char *host, int port, int timeout_ms, bool is_plain_tcp)
|
2018-08-07 13:56:59 -04:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
2018-08-07 13:56:59 -04:00
|
|
|
if (ssl->conn_state == TRANS_SSL_INIT) {
|
|
|
|
ssl->cfg.timeout_ms = timeout_ms;
|
2021-01-25 03:45:38 -05:00
|
|
|
ssl->cfg.is_plain_tcp = is_plain_tcp;
|
2018-08-07 13:56:59 -04:00
|
|
|
ssl->cfg.non_block = true;
|
|
|
|
ssl->ssl_initialized = true;
|
2019-04-09 10:08:05 -04:00
|
|
|
ssl->tls = esp_tls_init();
|
2018-08-07 13:56:59 -04:00
|
|
|
if (!ssl->tls) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
ssl->conn_state = TRANS_SSL_CONNECTING;
|
2021-05-19 06:45:24 -04:00
|
|
|
ssl->sockfd = INVALID_SOCKET;
|
2018-08-07 13:56:59 -04:00
|
|
|
}
|
|
|
|
if (ssl->conn_state == TRANS_SSL_CONNECTING) {
|
2021-05-19 06:36:36 -04:00
|
|
|
int progress = esp_tls_conn_new_async(host, strlen(host), port, &ssl->cfg, ssl->tls);
|
|
|
|
if (progress >= 0) {
|
2022-04-19 22:39:13 -04:00
|
|
|
if (esp_tls_get_conn_sockfd(ssl->tls, &ssl->sockfd) != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining socket fd for the session");
|
|
|
|
esp_tls_conn_destroy(ssl->tls);
|
|
|
|
return -1;
|
|
|
|
}
|
2021-05-19 06:36:36 -04:00
|
|
|
}
|
|
|
|
return progress;
|
|
|
|
|
2018-08-07 13:56:59 -04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-01-25 03:45:38 -05:00
|
|
|
static inline int ssl_connect_async(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-01-25 03:45:38 -05:00
|
|
|
return esp_tls_connect_async(t, host, port, timeout_ms, false);
|
|
|
|
}
|
2019-09-12 01:55:47 -04:00
|
|
|
|
2021-01-25 03:45:38 -05:00
|
|
|
static inline int tcp_connect_async(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
|
|
|
{
|
|
|
|
return esp_tls_connect_async(t, host, port, timeout_ms, true);
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
static int ssl_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
2021-01-23 03:46:06 -05:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
2021-01-23 03:46:06 -05:00
|
|
|
|
|
|
|
ssl->cfg.timeout_ms = timeout_ms;
|
2021-05-04 04:23:52 -04:00
|
|
|
ssl->cfg.is_plain_tcp = false;
|
2021-01-25 03:45:38 -05:00
|
|
|
|
2021-01-23 03:46:06 -05:00
|
|
|
ssl->ssl_initialized = true;
|
|
|
|
ssl->tls = esp_tls_init();
|
2021-03-19 09:51:43 -04:00
|
|
|
if (ssl->tls == NULL) {
|
|
|
|
ESP_LOGE(TAG, "Failed to initialize new connection object");
|
|
|
|
capture_tcp_transport_error(t, ERR_TCP_TRANSPORT_NO_MEM);
|
|
|
|
return -1;
|
|
|
|
}
|
2021-01-23 03:46:06 -05:00
|
|
|
if (esp_tls_conn_new_sync(host, strlen(host), port, &ssl->cfg, ssl->tls) <= 0) {
|
|
|
|
ESP_LOGE(TAG, "Failed to open a new connection");
|
2022-04-19 22:39:13 -04:00
|
|
|
esp_tls_error_handle_t esp_tls_error_handle;
|
|
|
|
esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle);
|
|
|
|
esp_transport_set_errors(t, esp_tls_error_handle);
|
|
|
|
goto exit_failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (esp_tls_get_conn_sockfd(ssl->tls, &ssl->sockfd) != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining socket fd for the session");
|
|
|
|
goto exit_failure;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
exit_failure:
|
2021-01-23 03:46:06 -05:00
|
|
|
esp_tls_conn_destroy(ssl->tls);
|
|
|
|
ssl->tls = NULL;
|
2021-05-19 06:45:24 -04:00
|
|
|
ssl->sockfd = INVALID_SOCKET;
|
2021-01-23 03:46:06 -05:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
|
2021-01-25 03:45:38 -05:00
|
|
|
{
|
2021-05-04 04:23:52 -04:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
|
|
|
esp_tls_last_error_t *err_handle = esp_transport_get_error_handle(t);
|
2021-01-25 03:45:38 -05:00
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
ssl->cfg.timeout_ms = timeout_ms;
|
2021-05-19 06:58:06 -04:00
|
|
|
esp_err_t err = esp_tls_plain_tcp_connect(host, strlen(host), port, &ssl->cfg, err_handle, &ssl->sockfd);
|
2021-05-04 04:23:52 -04:00
|
|
|
if (err != ESP_OK) {
|
|
|
|
ESP_LOGE(TAG, "Failed to open a new connection: %d", err);
|
|
|
|
err_handle->last_error = err;
|
2021-05-19 06:45:24 -04:00
|
|
|
ssl->sockfd = INVALID_SOCKET;
|
2021-05-04 04:23:52 -04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
2021-01-25 03:45:38 -05:00
|
|
|
}
|
2021-01-23 03:46:06 -05:00
|
|
|
|
2021-05-19 06:45:24 -04:00
|
|
|
static int base_poll_read(esp_transport_handle_t t, int timeout_ms)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
2019-09-12 01:55:47 -04:00
|
|
|
int ret = -1;
|
2020-08-21 04:31:40 -04:00
|
|
|
int remain = 0;
|
2019-11-12 11:42:51 -05:00
|
|
|
struct timeval timeout;
|
2017-11-13 22:16:20 -05:00
|
|
|
fd_set readset;
|
2019-09-12 01:55:47 -04:00
|
|
|
fd_set errset;
|
2017-11-13 22:16:20 -05:00
|
|
|
FD_ZERO(&readset);
|
2019-09-12 01:55:47 -04:00
|
|
|
FD_ZERO(&errset);
|
2021-05-04 04:23:52 -04:00
|
|
|
FD_SET(ssl->sockfd, &readset);
|
|
|
|
FD_SET(ssl->sockfd, &errset);
|
2017-11-13 22:16:20 -05:00
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
if (ssl->tls && (remain = esp_tls_get_bytes_avail(ssl->tls)) > 0) {
|
2020-08-21 04:31:40 -04:00
|
|
|
ESP_LOGD(TAG, "remain data in cache, need to read again");
|
|
|
|
return remain;
|
|
|
|
}
|
2021-05-04 04:23:52 -04:00
|
|
|
ret = select(ssl->sockfd + 1, &readset, NULL, &errset, esp_transport_utils_ms_to_timeval(timeout_ms, &timeout));
|
|
|
|
if (ret > 0 && FD_ISSET(ssl->sockfd, &errset)) {
|
2019-09-12 01:55:47 -04:00
|
|
|
int sock_errno = 0;
|
|
|
|
uint32_t optlen = sizeof(sock_errno);
|
2021-05-04 04:23:52 -04:00
|
|
|
getsockopt(ssl->sockfd, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
|
2020-04-08 14:04:33 -04:00
|
|
|
esp_transport_capture_errno(t, sock_errno);
|
2021-05-19 06:36:36 -04:00
|
|
|
ESP_LOGE(TAG, "poll_read select error %d, errno = %s, fd = %d", sock_errno, strerror(sock_errno), ssl->sockfd);
|
2019-09-12 01:55:47 -04:00
|
|
|
ret = -1;
|
2022-03-07 00:29:54 -05:00
|
|
|
} else if (ret == 0) {
|
|
|
|
ESP_LOGD(TAG, "poll_read: select - Timeout before any socket was ready!");
|
2019-09-12 01:55:47 -04:00
|
|
|
}
|
|
|
|
return ret;
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
|
|
|
|
2021-05-19 06:45:24 -04:00
|
|
|
static int base_poll_write(esp_transport_handle_t t, int timeout_ms)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
2019-09-12 01:55:47 -04:00
|
|
|
int ret = -1;
|
2019-11-12 11:42:51 -05:00
|
|
|
struct timeval timeout;
|
2017-11-13 22:16:20 -05:00
|
|
|
fd_set writeset;
|
2019-09-12 01:55:47 -04:00
|
|
|
fd_set errset;
|
2017-11-13 22:16:20 -05:00
|
|
|
FD_ZERO(&writeset);
|
2019-09-12 01:55:47 -04:00
|
|
|
FD_ZERO(&errset);
|
2021-05-04 04:23:52 -04:00
|
|
|
FD_SET(ssl->sockfd, &writeset);
|
|
|
|
FD_SET(ssl->sockfd, &errset);
|
|
|
|
ret = select(ssl->sockfd + 1, NULL, &writeset, &errset, esp_transport_utils_ms_to_timeval(timeout_ms, &timeout));
|
|
|
|
if (ret > 0 && FD_ISSET(ssl->sockfd, &errset)) {
|
2019-09-12 01:55:47 -04:00
|
|
|
int sock_errno = 0;
|
|
|
|
uint32_t optlen = sizeof(sock_errno);
|
2021-05-04 04:23:52 -04:00
|
|
|
getsockopt(ssl->sockfd, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
|
2020-04-08 14:04:33 -04:00
|
|
|
esp_transport_capture_errno(t, sock_errno);
|
2021-05-19 06:36:36 -04:00
|
|
|
ESP_LOGE(TAG, "poll_write select error %d, errno = %s, fd = %d", sock_errno, strerror(sock_errno), ssl->sockfd);
|
2019-09-12 01:55:47 -04:00
|
|
|
ret = -1;
|
2022-03-07 00:29:54 -05:00
|
|
|
} else if (ret == 0) {
|
|
|
|
ESP_LOGD(TAG, "poll_write: select - Timeout before any socket was ready!");
|
2019-09-12 01:55:47 -04:00
|
|
|
}
|
|
|
|
return ret;
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
|
|
|
|
2018-09-26 05:56:47 -04:00
|
|
|
static int ssl_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-05-04 04:23:52 -04:00
|
|
|
int poll;
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
2017-11-13 22:16:20 -05:00
|
|
|
|
2018-09-26 05:56:47 -04:00
|
|
|
if ((poll = esp_transport_poll_write(t, timeout_ms)) <= 0) {
|
2021-05-19 06:36:36 -04:00
|
|
|
ESP_LOGW(TAG, "Poll timeout or error, errno=%s, fd=%d, timeout_ms=%d", strerror(errno), ssl->sockfd, timeout_ms);
|
2017-11-13 22:16:20 -05:00
|
|
|
return poll;
|
|
|
|
}
|
2021-05-04 04:23:52 -04:00
|
|
|
int ret = esp_tls_conn_write(ssl->tls, (const unsigned char *) buffer, len);
|
2019-01-07 03:33:41 -05:00
|
|
|
if (ret < 0) {
|
2018-08-07 13:56:59 -04:00
|
|
|
ESP_LOGE(TAG, "esp_tls_conn_write error, errno=%s", strerror(errno));
|
2022-04-19 22:39:13 -04:00
|
|
|
esp_tls_error_handle_t esp_tls_error_handle;
|
|
|
|
if (esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle) == ESP_OK) {
|
|
|
|
esp_transport_set_errors(t, esp_tls_error_handle);
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining the error handle");
|
|
|
|
}
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
static int tcp_write(esp_transport_handle_t t, const char *buffer, int len, int timeout_ms)
|
|
|
|
{
|
|
|
|
int poll;
|
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
|
|
|
|
|
|
|
if ((poll = esp_transport_poll_write(t, timeout_ms)) <= 0) {
|
2021-05-19 06:36:36 -04:00
|
|
|
ESP_LOGW(TAG, "Poll timeout or error, errno=%s, fd=%d, timeout_ms=%d", strerror(errno), ssl->sockfd, timeout_ms);
|
2021-05-04 04:23:52 -04:00
|
|
|
return poll;
|
|
|
|
}
|
|
|
|
int ret = send(ssl->sockfd,(const unsigned char *) buffer, len, 0);
|
|
|
|
if (ret < 0) {
|
|
|
|
ESP_LOGE(TAG, "tcp_write error, errno=%s", strerror(errno));
|
|
|
|
esp_transport_capture_errno(t, errno);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-09-26 05:56:47 -04:00
|
|
|
static int ssl_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
2018-07-27 08:48:26 -04:00
|
|
|
|
2022-03-07 00:29:54 -05:00
|
|
|
int poll = esp_transport_poll_read(t, timeout_ms);
|
|
|
|
if (poll == -1) {
|
|
|
|
return ERR_TCP_TRANSPORT_CONNECTION_FAILED;
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
2022-03-07 00:29:54 -05:00
|
|
|
if (poll == 0) {
|
|
|
|
return ERR_TCP_TRANSPORT_CONNECTION_TIMEOUT;
|
|
|
|
}
|
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
int ret = esp_tls_conn_read(ssl->tls, (unsigned char *)buffer, len);
|
2019-01-07 03:33:41 -05:00
|
|
|
if (ret < 0) {
|
2018-08-07 13:56:59 -04:00
|
|
|
ESP_LOGE(TAG, "esp_tls_conn_read error, errno=%s", strerror(errno));
|
2022-03-07 00:29:54 -05:00
|
|
|
if (ret == ESP_TLS_ERR_SSL_WANT_READ || ret == ESP_TLS_ERR_SSL_TIMEOUT) {
|
|
|
|
ret = ERR_TCP_TRANSPORT_CONNECTION_TIMEOUT;
|
|
|
|
}
|
|
|
|
|
2022-04-19 22:39:13 -04:00
|
|
|
esp_tls_error_handle_t esp_tls_error_handle;
|
|
|
|
if (esp_tls_get_error_handle(ssl->tls, &esp_tls_error_handle) == ESP_OK) {
|
|
|
|
esp_transport_set_errors(t, esp_tls_error_handle);
|
|
|
|
} else {
|
|
|
|
ESP_LOGE(TAG, "Error in obtaining the error handle");
|
|
|
|
}
|
2022-03-07 00:29:54 -05:00
|
|
|
} else if (ret == 0) {
|
2021-01-22 15:00:22 -05:00
|
|
|
if (poll > 0) {
|
|
|
|
// no error, socket reads 0 while previously detected as readable -> connection has been closed cleanly
|
|
|
|
capture_tcp_transport_error(t, ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN);
|
|
|
|
}
|
2022-03-07 00:29:54 -05:00
|
|
|
ret = ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN;
|
2019-01-19 05:13:22 -05:00
|
|
|
}
|
2017-11-13 22:16:20 -05:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
static int tcp_read(esp_transport_handle_t t, char *buffer, int len, int timeout_ms)
|
|
|
|
{
|
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
|
|
|
|
2022-03-07 00:29:54 -05:00
|
|
|
int poll = esp_transport_poll_read(t, timeout_ms);
|
|
|
|
if (poll == -1) {
|
|
|
|
return ERR_TCP_TRANSPORT_CONNECTION_FAILED;
|
2021-05-04 04:23:52 -04:00
|
|
|
}
|
2022-03-07 00:29:54 -05:00
|
|
|
if (poll == 0) {
|
|
|
|
return ERR_TCP_TRANSPORT_CONNECTION_TIMEOUT;
|
|
|
|
}
|
|
|
|
|
2021-05-04 04:23:52 -04:00
|
|
|
int ret = recv(ssl->sockfd, (unsigned char *)buffer, len, 0);
|
|
|
|
if (ret < 0) {
|
|
|
|
ESP_LOGE(TAG, "tcp_read error, errno=%s", strerror(errno));
|
|
|
|
esp_transport_capture_errno(t, errno);
|
2022-03-07 00:29:54 -05:00
|
|
|
if (errno == EAGAIN) {
|
|
|
|
ret = ERR_TCP_TRANSPORT_CONNECTION_TIMEOUT;
|
|
|
|
}
|
|
|
|
} else if (ret == 0) {
|
2021-05-04 04:23:52 -04:00
|
|
|
if (poll > 0) {
|
|
|
|
// no error, socket reads 0 while previously detected as readable -> connection has been closed cleanly
|
|
|
|
capture_tcp_transport_error(t, ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN);
|
|
|
|
}
|
2022-03-07 00:29:54 -05:00
|
|
|
ret = ERR_TCP_TRANSPORT_CONNECTION_CLOSED_BY_FIN;
|
2021-05-04 04:23:52 -04:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-05-19 06:45:24 -04:00
|
|
|
static int base_close(esp_transport_handle_t t)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
|
|
|
int ret = -1;
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
|
|
|
if (ssl && ssl->ssl_initialized) {
|
2020-04-28 06:16:03 -04:00
|
|
|
ret = esp_tls_conn_destroy(ssl->tls);
|
2021-06-20 15:21:22 -04:00
|
|
|
ssl->tls = NULL;
|
2020-04-15 05:52:32 -04:00
|
|
|
ssl->conn_state = TRANS_SSL_INIT;
|
2017-11-13 22:16:20 -05:00
|
|
|
ssl->ssl_initialized = false;
|
2021-05-19 06:45:24 -04:00
|
|
|
ssl->sockfd = INVALID_SOCKET;
|
2021-05-04 04:23:52 -04:00
|
|
|
} else if (ssl && ssl->sockfd >= 0) {
|
2022-02-03 07:45:11 -05:00
|
|
|
ret = close(ssl->sockfd);
|
2021-05-19 06:45:24 -04:00
|
|
|
ssl->sockfd = INVALID_SOCKET;
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2021-05-19 06:45:24 -04:00
|
|
|
static int base_destroy(esp_transport_handle_t t)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
transport_esp_tls_t *ssl = ssl_get_context_data(t);
|
|
|
|
if (ssl) {
|
|
|
|
esp_transport_close(t);
|
|
|
|
if (t->base && t->base->transport_esp_tls &&
|
|
|
|
t->data == t->base->transport_esp_tls) {
|
|
|
|
// if internal ssl the same as the foundation transport,
|
|
|
|
// just zero out, it will be freed on list destroy
|
|
|
|
t->data = NULL;
|
|
|
|
}
|
|
|
|
esp_transport_esp_tls_destroy(t->data); // okay to pass NULL
|
|
|
|
}
|
2017-11-13 22:16:20 -05:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-02-20 02:18:45 -05:00
|
|
|
void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.use_global_ca_store = true;
|
2019-02-20 02:18:45 -05:00
|
|
|
}
|
|
|
|
|
2021-04-14 04:30:54 -04:00
|
|
|
#ifdef CONFIG_ESP_TLS_PSK_VERIFICATION
|
2019-05-23 15:48:08 -04:00
|
|
|
void esp_transport_ssl_set_psk_key_hint(esp_transport_handle_t t, const psk_hint_key_t* psk_hint_key)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.psk_hint_key = psk_hint_key;
|
2019-05-23 15:48:08 -04:00
|
|
|
}
|
2021-04-14 04:30:54 -04:00
|
|
|
#endif
|
2019-05-23 15:48:08 -04:00
|
|
|
|
2018-09-26 05:56:47 -04:00
|
|
|
void esp_transport_ssl_set_cert_data(esp_transport_handle_t t, const char *data, int len)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.cacert_pem_buf = (void *)data;
|
|
|
|
ssl->cfg.cacert_pem_bytes = len + 1;
|
2017-11-13 22:16:20 -05:00
|
|
|
}
|
|
|
|
|
2019-07-15 11:53:39 -04:00
|
|
|
void esp_transport_ssl_set_cert_data_der(esp_transport_handle_t t, const char *data, int len)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.cacert_buf = (void *)data;
|
|
|
|
ssl->cfg.cacert_bytes = len;
|
2019-07-15 11:53:39 -04:00
|
|
|
}
|
|
|
|
|
2018-09-28 12:45:37 -04:00
|
|
|
void esp_transport_ssl_set_client_cert_data(esp_transport_handle_t t, const char *data, int len)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.clientcert_pem_buf = (void *)data;
|
|
|
|
ssl->cfg.clientcert_pem_bytes = len + 1;
|
2018-09-28 12:45:37 -04:00
|
|
|
}
|
|
|
|
|
2019-07-15 11:53:39 -04:00
|
|
|
void esp_transport_ssl_set_client_cert_data_der(esp_transport_handle_t t, const char *data, int len)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.clientcert_buf = (void *)data;
|
|
|
|
ssl->cfg.clientcert_bytes = len;
|
2019-07-15 11:53:39 -04:00
|
|
|
}
|
|
|
|
|
2018-09-28 12:45:37 -04:00
|
|
|
void esp_transport_ssl_set_client_key_data(esp_transport_handle_t t, const char *data, int len)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.clientkey_pem_buf = (void *)data;
|
|
|
|
ssl->cfg.clientkey_pem_bytes = len + 1;
|
2018-09-28 12:45:37 -04:00
|
|
|
}
|
|
|
|
|
2019-12-30 02:40:50 -05:00
|
|
|
void esp_transport_ssl_set_client_key_password(esp_transport_handle_t t, const char *password, int password_len)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.clientkey_password = (void *)password;
|
|
|
|
ssl->cfg.clientkey_password_len = password_len;
|
2019-12-30 02:40:50 -05:00
|
|
|
}
|
|
|
|
|
2019-07-15 11:53:39 -04:00
|
|
|
void esp_transport_ssl_set_client_key_data_der(esp_transport_handle_t t, const char *data, int len)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.clientkey_buf = (void *)data;
|
|
|
|
ssl->cfg.clientkey_bytes = len;
|
2019-07-15 11:53:39 -04:00
|
|
|
}
|
|
|
|
|
2021-04-14 04:30:54 -04:00
|
|
|
#if defined(CONFIG_MBEDTLS_SSL_ALPN) || defined(CONFIG_WOLFSSL_HAVE_ALPN)
|
2019-11-12 21:36:24 -05:00
|
|
|
void esp_transport_ssl_set_alpn_protocol(esp_transport_handle_t t, const char **alpn_protos)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.alpn_protos = alpn_protos;
|
2019-11-12 21:36:24 -05:00
|
|
|
}
|
2021-04-14 04:30:54 -04:00
|
|
|
#endif
|
2019-11-12 21:36:24 -05:00
|
|
|
|
2019-06-12 04:41:00 -04:00
|
|
|
void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.skip_common_name = true;
|
2019-06-12 04:41:00 -04:00
|
|
|
}
|
|
|
|
|
2021-04-14 04:30:54 -04:00
|
|
|
#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT
|
2020-04-06 10:42:52 -04:00
|
|
|
void esp_transport_ssl_use_secure_element(esp_transport_handle_t t)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.use_secure_element = true;
|
2020-04-06 10:42:52 -04:00
|
|
|
}
|
2021-04-14 04:30:54 -04:00
|
|
|
#endif
|
2020-04-06 10:42:52 -04:00
|
|
|
|
2021-04-14 04:30:54 -04:00
|
|
|
#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
2021-04-04 03:40:34 -04:00
|
|
|
void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*crt_bundle_attach)(void *conf)))
|
|
|
|
{
|
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.crt_bundle_attach = crt_bundle_attach;
|
|
|
|
}
|
2021-04-14 04:30:54 -04:00
|
|
|
#endif
|
2021-04-04 03:40:34 -04:00
|
|
|
|
2021-05-19 06:45:24 -04:00
|
|
|
static int base_get_socket(esp_transport_handle_t t)
|
2021-05-04 04:23:52 -04:00
|
|
|
{
|
|
|
|
transport_esp_tls_t *ctx = ssl_get_context_data(t);
|
|
|
|
if (ctx) {
|
|
|
|
return ctx->sockfd;
|
|
|
|
}
|
2021-05-19 06:45:24 -04:00
|
|
|
return INVALID_SOCKET;
|
2021-05-04 04:23:52 -04:00
|
|
|
}
|
|
|
|
|
2021-04-14 04:30:54 -04:00
|
|
|
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
2020-07-31 04:27:25 -04:00
|
|
|
void esp_transport_ssl_set_ds_data(esp_transport_handle_t t, void *ds_data)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.ds_data = ds_data;
|
2020-07-31 04:27:25 -04:00
|
|
|
}
|
2021-04-14 04:30:54 -04:00
|
|
|
#endif
|
2020-07-31 04:27:25 -04:00
|
|
|
|
2021-01-06 03:58:39 -05:00
|
|
|
void esp_transport_ssl_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
|
|
|
{
|
2021-02-04 04:18:56 -05:00
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.keep_alive_cfg = (tls_keep_alive_cfg_t *) keep_alive_cfg;
|
2021-01-06 03:58:39 -05:00
|
|
|
}
|
|
|
|
|
2021-01-19 04:49:42 -05:00
|
|
|
void esp_transport_ssl_set_interface_name(esp_transport_handle_t t, struct ifreq *if_name)
|
|
|
|
{
|
|
|
|
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
|
|
|
|
ssl->cfg.if_name = if_name;
|
|
|
|
}
|
|
|
|
|
2019-07-16 05:33:30 -04:00
|
|
|
esp_transport_handle_t esp_transport_ssl_init(void)
|
2017-11-13 22:16:20 -05:00
|
|
|
{
|
2018-09-26 05:56:47 -04:00
|
|
|
esp_transport_handle_t t = esp_transport_init();
|
2021-05-03 03:46:28 -04:00
|
|
|
if (t == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-05-19 06:45:24 -04:00
|
|
|
esp_transport_set_func(t, ssl_connect, ssl_read, ssl_write, base_close, base_poll_read, base_poll_write, base_destroy);
|
2018-09-26 05:56:47 -04:00
|
|
|
esp_transport_set_async_connect_func(t, ssl_connect_async);
|
2021-05-19 06:45:24 -04:00
|
|
|
t->_get_socket = base_get_socket;
|
2017-11-13 22:16:20 -05:00
|
|
|
return t;
|
|
|
|
}
|
2021-01-23 03:46:06 -05:00
|
|
|
|
2021-01-25 03:45:38 -05:00
|
|
|
struct transport_esp_tls* esp_transport_esp_tls_create(void)
|
|
|
|
{
|
|
|
|
transport_esp_tls_t *transport_esp_tls = calloc(1, sizeof(transport_esp_tls_t));
|
2021-09-07 23:04:08 -04:00
|
|
|
if (transport_esp_tls == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-05-19 06:45:24 -04:00
|
|
|
transport_esp_tls->sockfd = INVALID_SOCKET;
|
2021-01-25 03:45:38 -05:00
|
|
|
return transport_esp_tls;
|
|
|
|
}
|
|
|
|
|
|
|
|
void esp_transport_esp_tls_destroy(struct transport_esp_tls* transport_esp_tls)
|
2021-01-23 03:46:06 -05:00
|
|
|
{
|
2021-01-25 03:45:38 -05:00
|
|
|
free(transport_esp_tls);
|
2021-01-23 03:46:06 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
esp_transport_handle_t esp_transport_tcp_init(void)
|
|
|
|
{
|
|
|
|
esp_transport_handle_t t = esp_transport_init();
|
2021-05-03 03:46:28 -04:00
|
|
|
if (t == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-05-19 06:45:24 -04:00
|
|
|
esp_transport_set_func(t, tcp_connect, tcp_read, tcp_write, base_close, base_poll_read, base_poll_write, base_destroy);
|
2021-01-25 03:45:38 -05:00
|
|
|
esp_transport_set_async_connect_func(t, tcp_connect_async);
|
2021-05-19 06:45:24 -04:00
|
|
|
t->_get_socket = base_get_socket;
|
2021-01-23 03:46:06 -05:00
|
|
|
return t;
|
|
|
|
}
|
2021-01-25 03:45:38 -05:00
|
|
|
|
|
|
|
void esp_transport_tcp_set_keep_alive(esp_transport_handle_t t, esp_transport_keep_alive_t *keep_alive_cfg)
|
|
|
|
{
|
|
|
|
return esp_transport_ssl_set_keep_alive(t, keep_alive_cfg);
|
|
|
|
}
|
2021-01-19 04:49:42 -05:00
|
|
|
|
|
|
|
void esp_transport_tcp_set_interface_name(esp_transport_handle_t t, struct ifreq *if_name)
|
|
|
|
{
|
|
|
|
return esp_transport_ssl_set_interface_name(t, if_name);
|
|
|
|
}
|