mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
esp-tls: Add support for https_server using wolfSSL
This commit is contained in:
parent
5ea4d7ba61
commit
d35862b662
@ -15,10 +15,10 @@ menu "ESP-TLS"
|
||||
|
||||
config ESP_TLS_SERVER
|
||||
bool "Enable ESP-TLS Server"
|
||||
depends on ESP_TLS_USING_MBEDTLS
|
||||
default n
|
||||
help
|
||||
Enable support for creating server side SSL/TLS session, uses the mbedtls crypto library
|
||||
Enable support for creating server side SSL/TLS session, available for mbedTLS
|
||||
as well as wolfSSL TLS library.
|
||||
|
||||
config ESP_TLS_PSK_VERIFICATION
|
||||
bool "Enable PSK verification"
|
||||
|
@ -60,6 +60,10 @@ static const char *TAG = "esp-tls";
|
||||
#define _esp_tls_read esp_wolfssl_read
|
||||
#define _esp_tls_write esp_wolfssl_write
|
||||
#define _esp_tls_conn_delete esp_wolfssl_conn_delete
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
#define _esp_tls_server_session_create esp_wolfssl_server_session_create
|
||||
#define _esp_tls_server_session_delete esp_wolfssl_server_session_delete
|
||||
#endif /* CONFIG_ESP_TLS_SERVER */
|
||||
#define _esp_tls_get_bytes_avail esp_wolfssl_get_bytes_avail
|
||||
#define _esp_tls_init_global_ca_store esp_wolfssl_init_global_ca_store
|
||||
#define _esp_tls_set_global_ca_store esp_wolfssl_set_global_ca_store /*!< Callback function for setting global CA store data for TLS/SSL */
|
||||
@ -429,6 +433,7 @@ mbedtls_x509_crt *esp_tls_get_global_ca_store(void)
|
||||
return _esp_tls_get_global_ca_store();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
/**
|
||||
* @brief Create a server side TLS/SSL connection
|
||||
@ -445,7 +450,6 @@ void esp_tls_server_session_delete(esp_tls_t *tls)
|
||||
return _esp_tls_server_session_delete(tls);
|
||||
}
|
||||
#endif /* CONFIG_ESP_TLS_SERVER */
|
||||
#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
|
||||
|
||||
ssize_t esp_tls_get_bytes_avail(esp_tls_t *tls)
|
||||
{
|
||||
|
@ -562,6 +562,7 @@ esp_err_t esp_tls_get_and_clear_last_error(esp_tls_error_handle_t h, int *esp_tl
|
||||
*/
|
||||
mbedtls_x509_crt *esp_tls_get_global_ca_store(void);
|
||||
|
||||
#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
/**
|
||||
* @brief Create TLS/SSL server session
|
||||
@ -589,7 +590,6 @@ int esp_tls_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls
|
||||
*/
|
||||
void esp_tls_server_session_delete(esp_tls_t *tls);
|
||||
#endif /* ! CONFIG_ESP_TLS_SERVER */
|
||||
#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -31,16 +31,18 @@ static unsigned char *global_cacert = NULL;
|
||||
static unsigned int global_cacert_pem_bytes = 0;
|
||||
static const char *TAG = "esp-tls-wolfssl";
|
||||
|
||||
int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg1, esp_tls_t *tls)
|
||||
esp_err_t esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *cfg, esp_tls_t *tls)
|
||||
{
|
||||
#ifdef CONFIG_ESP_DEBUG_WOLFSSL
|
||||
wolfSSL_Debugging_ON();
|
||||
#endif
|
||||
const esp_tls_cfg_t *cfg = cfg1;
|
||||
|
||||
assert(cfg != NULL);
|
||||
assert(tls != NULL);
|
||||
|
||||
esp_err_t esp_ret = ESP_FAIL;
|
||||
int ret;
|
||||
|
||||
ret = wolfSSL_Init();
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Init wolfSSL failed: %d", ret);
|
||||
@ -48,6 +50,33 @@ int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (tls->role == ESP_TLS_CLIENT) {
|
||||
esp_ret = set_client_config(hostname, hostlen, (esp_tls_cfg_t *)cfg, tls);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set client configurations");
|
||||
goto exit;
|
||||
}
|
||||
} else if (tls->role == ESP_TLS_SERVER) {
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
esp_ret = set_server_config((esp_tls_cfg_server_t *) cfg, tls);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set server configurations");
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
ESP_LOGE(TAG, "ESP_TLS_SERVER Not enabled in Kconfig");
|
||||
goto exit;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
exit:
|
||||
esp_wolfssl_cleanup(tls);
|
||||
return esp_ret;
|
||||
}
|
||||
|
||||
esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls)
|
||||
{
|
||||
tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_client_method());
|
||||
if (!tls->priv_ctx) {
|
||||
ESP_LOGE(TAG, "Set wolfSSL ctx failed");
|
||||
@ -70,22 +99,22 @@ int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *
|
||||
|
||||
if ( cfg->use_global_ca_store == true) {
|
||||
wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, global_cacert, global_cacert_pem_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, SSL_VERIFY_PEER, NULL);
|
||||
} else if (cfg->cacert_pem_buf != NULL) {
|
||||
wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->cacert_pem_buf, cfg->cacert_pem_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, SSL_VERIFY_PEER, NULL);
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
} else if (cfg->cacert_buf != NULL) {
|
||||
wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->cacert_buf, cfg->cacert_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER, NULL);
|
||||
} else if (cfg->psk_hint_key) {
|
||||
ESP_LOGE(TAG,"psk_hint_key not supported in wolfssl");
|
||||
goto exit;
|
||||
} else {
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, SSL_VERIFY_NONE, NULL);
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
|
||||
}
|
||||
|
||||
if (cfg->clientcert_pem_buf != NULL && cfg->clientkey_pem_buf != NULL) {
|
||||
wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->clientcert_pem_buf, cfg->clientcert_pem_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->clientkey_pem_buf, cfg->clientkey_pem_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
} else if (cfg->clientcert_pem_buf != NULL || cfg->clientkey_pem_buf != NULL) {
|
||||
ESP_LOGE(TAG, "You have to provide both clientcert_pem_buf and clientkey_pem_buf for mutual authentication\n\n");
|
||||
if (cfg->clientcert_buf != NULL && cfg->clientkey_buf != NULL) {
|
||||
wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->clientcert_buf, cfg->clientcert_pem_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->clientkey_buf, cfg->clientkey_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
} else if (cfg->clientcert_buf != NULL || cfg->clientkey_buf != NULL) {
|
||||
ESP_LOGE(TAG, "You have to provide both clientcert_buf and clientkey_buf for mutual authentication\n\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -105,13 +134,63 @@ int esp_create_wolfssl_handle(const char *hostname, size_t hostlen, const void *
|
||||
wolfSSL_set_tlsext_host_name( (WOLFSSL *)tls->priv_ssl, use_host);
|
||||
free(use_host);
|
||||
#endif
|
||||
wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
|
||||
return ESP_OK;
|
||||
exit:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls)
|
||||
{
|
||||
tls->priv_ctx = (void *)wolfSSL_CTX_new(wolfTLSv1_2_server_method());
|
||||
if (!tls->priv_ctx) {
|
||||
ESP_LOGE(TAG, "Set wolfSSL ctx failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ALPN
|
||||
if (cfg->alpn_protos) {
|
||||
char **alpn_list = (char **)cfg->alpn_protos;
|
||||
for (; *alpn_list != NULL; alpn_list ++) {
|
||||
if (wolfSSL_UseALPN( (WOLFSSL *)tls->priv_ssl, *alpn_list, strlen(*alpn_list), WOLFSSL_ALPN_FAILED_ON_MISMATCH) != WOLFSSL_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Use wolfSSL ALPN failed");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (cfg->cacert_buf != NULL) {
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
if (wolfSSL_CTX_load_verify_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->cacert_buf, cfg->cacert_bytes, WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
ESP_LOGD(TAG," Verify Client for Mutual Auth");
|
||||
} else {
|
||||
ESP_LOGD(TAG," Not verifying Client ");
|
||||
wolfSSL_CTX_set_verify( (WOLFSSL_CTX *)tls->priv_ctx, WOLFSSL_VERIFY_NONE, NULL);
|
||||
}
|
||||
|
||||
if (cfg->servercert_buf != NULL && cfg->serverkey_buf != NULL) {
|
||||
wolfSSL_CTX_use_certificate_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->servercert_buf, cfg->servercert_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
wolfSSL_CTX_use_PrivateKey_buffer( (WOLFSSL_CTX *)tls->priv_ctx, cfg->serverkey_buf, cfg->serverkey_bytes, WOLFSSL_FILETYPE_PEM);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "You have to provide both servercert_buf and serverkey_buf for https_server\n\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tls->priv_ssl =(void *)wolfSSL_new( (WOLFSSL_CTX *)tls->priv_ctx);
|
||||
if (!tls->priv_ssl) {
|
||||
ESP_LOGE(TAG, "Create wolfSSL failed");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
wolfSSL_set_fd((WOLFSSL *)tls->priv_ssl, tls->sockfd);
|
||||
return 0;
|
||||
return ESP_OK;
|
||||
exit:
|
||||
esp_wolfssl_cleanup(tls);
|
||||
return ret;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg)
|
||||
{
|
||||
@ -126,7 +205,7 @@ int esp_wolfssl_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg)
|
||||
ESP_LOGE(TAG, "wolfSSL_connect returned -0x%x", -ret);
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_WOLFSSL, -ret);
|
||||
|
||||
if (cfg->cacert_pem_buf != NULL || cfg->use_global_ca_store == true) {
|
||||
if (cfg->cacert_buf != NULL || cfg->use_global_ca_store == true) {
|
||||
/* This is to check whether handshake failed due to invalid certificate*/
|
||||
esp_wolfssl_verify_certificate(tls);
|
||||
}
|
||||
@ -208,6 +287,50 @@ void esp_wolfssl_cleanup(esp_tls_t *tls)
|
||||
wolfSSL_Cleanup();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
/**
|
||||
* @brief Create TLS/SSL server session
|
||||
*/
|
||||
int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls)
|
||||
{
|
||||
if (tls == NULL || cfg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
tls->role = ESP_TLS_SERVER;
|
||||
tls->sockfd = sockfd;
|
||||
esp_err_t esp_ret = esp_create_wolfssl_handle(NULL, 0, cfg, tls);
|
||||
if (esp_ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "create_ssl_handle failed");
|
||||
ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_ESP, esp_ret);
|
||||
tls->conn_state = ESP_TLS_FAIL;
|
||||
return -1;
|
||||
}
|
||||
tls->read = esp_wolfssl_read;
|
||||
tls->write = esp_wolfssl_write;
|
||||
|
||||
int ret;
|
||||
while ((ret = wolfSSL_accept((WOLFSSL *)tls->priv_ssl)) != WOLFSSL_SUCCESS) {
|
||||
if (ret != ESP_TLS_ERR_SSL_WANT_READ && ret != ESP_TLS_ERR_SSL_WANT_WRITE) {
|
||||
ESP_LOGE(TAG, "wolfSSL_handshake returned %d", ret);
|
||||
tls->conn_state = ESP_TLS_FAIL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close the server side TLS/SSL connection and free any allocated resources.
|
||||
*/
|
||||
void esp_wolfssl_server_session_delete(esp_tls_t *tls)
|
||||
{
|
||||
if (tls != NULL) {
|
||||
esp_wolfssl_cleanup(tls);
|
||||
free(tls);
|
||||
}
|
||||
};
|
||||
#endif /* ! CONFIG_ESP_TLS_SERVER */
|
||||
|
||||
esp_err_t esp_wolfssl_init_global_ca_store(void)
|
||||
{
|
||||
/* This function is just to provide consistancy between function calls of esp_tls.h and wolfssl */
|
||||
|
@ -35,6 +35,11 @@ ssize_t esp_wolfssl_read(esp_tls_t *tls, char *data, size_t datalen);
|
||||
*/
|
||||
ssize_t esp_wolfssl_write(esp_tls_t *tls, const char *data, size_t datalen);
|
||||
|
||||
/**
|
||||
* Configures the SSL/TLS connection for client method
|
||||
*/
|
||||
esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t *cfg, esp_tls_t *tls);
|
||||
|
||||
/**
|
||||
* Internal Callback for wolfssl_cleanup , frees up all the memory used by wolfssl
|
||||
*/
|
||||
@ -70,3 +75,22 @@ void esp_wolfssl_free_global_ca_store(void);
|
||||
* Callback function for Initializing the global ca store for TLS?SSL using wolfssl
|
||||
*/
|
||||
esp_err_t esp_wolfssl_init_global_ca_store(void);
|
||||
|
||||
#ifdef CONFIG_ESP_TLS_SERVER
|
||||
|
||||
/**
|
||||
* Configures the SSL/TLS connection for server method
|
||||
*/
|
||||
esp_err_t set_server_config(esp_tls_cfg_server_t *cfg, esp_tls_t *tls);
|
||||
|
||||
/**
|
||||
* Function to Create ESP-TLS Server session with wolfssl Stack
|
||||
*/
|
||||
int esp_wolfssl_server_session_create(esp_tls_cfg_server_t *cfg, int sockfd, esp_tls_t *tls);
|
||||
|
||||
/*
|
||||
* Delete Server Session
|
||||
*/
|
||||
void esp_wolfssl_server_session_delete(esp_tls_t *tls);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user