mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-17 20:42:21 +02:00
feat(tls_cxx): Publish mbedtls component
Adds examples and tests. Also supports DTLS now.
This commit is contained in:
11
components/mbedtls_cxx/examples/tls_client/CMakeLists.txt
Normal file
11
components/mbedtls_cxx/examples/tls_client/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# For more information about build system see
|
||||
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
if("${IDF_TARGET}" STREQUAL "linux")
|
||||
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/")
|
||||
endif()
|
||||
project(tls_client)
|
4
components/mbedtls_cxx/examples/tls_client/README.md
Normal file
4
components/mbedtls_cxx/examples/tls_client/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# TCP client example
|
||||
|
||||
This is a simple example uses `mbedtls_cxx` to connect to a remote echo server.
|
||||
The example needs a connection to internet (or a network where the TLS echo-server is available), it could be run on linux target as well as on ESP32.
|
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "tls_client.cpp"
|
||||
INCLUDE_DIRS ".")
|
@ -0,0 +1,7 @@
|
||||
dependencies:
|
||||
idf: ">=5.0"
|
||||
espressif/mbedtls_cxx:
|
||||
version: "*"
|
||||
override_path: "../../.."
|
||||
protocol_examples_common:
|
||||
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
|
152
components/mbedtls_cxx/examples/tls_client/main/tls_client.cpp
Normal file
152
components/mbedtls_cxx/examples/tls_client/main/tls_client.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include "esp_log.h"
|
||||
#include "mbedtls_wrap.hpp"
|
||||
|
||||
using namespace idf::mbedtls_cxx;
|
||||
|
||||
namespace {
|
||||
constexpr auto *TAG = "simple_tls_client";
|
||||
}
|
||||
|
||||
class TlsSocketClient: public Tls {
|
||||
public:
|
||||
TlsSocketClient() = default;
|
||||
~TlsSocketClient() override
|
||||
{
|
||||
if (sock >= 0) {
|
||||
::close(sock);
|
||||
}
|
||||
}
|
||||
int send(const unsigned char *buf, size_t len) override
|
||||
{
|
||||
return ::send(sock, buf, len, 0);
|
||||
}
|
||||
int recv(unsigned char *buf, size_t len) override
|
||||
{
|
||||
return ::recv(sock, buf, len, 0);
|
||||
}
|
||||
bool connect(const char *host, int port)
|
||||
{
|
||||
addr_info addr(host, AF_INET, SOCK_STREAM);
|
||||
if (!addr) {
|
||||
ESP_LOGE(TAG, "Failed to resolve host");
|
||||
return false;
|
||||
}
|
||||
sock = addr.get_sock();
|
||||
if (sock < 0) {
|
||||
ESP_LOGE(TAG, "Failed to create socket");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::connect(sock, addr.get_addr(port), sizeof(struct sockaddr)) < 0) {
|
||||
ESP_LOGE(TAG, "Failed to connect %d", errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!init(is_server{false}, do_verify{false})) {
|
||||
return false;
|
||||
}
|
||||
return handshake() == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
int sock{-1};
|
||||
/**
|
||||
* RAII wrapper of the address_info
|
||||
*/
|
||||
struct addr_info {
|
||||
struct addrinfo *ai {
|
||||
nullptr
|
||||
};
|
||||
~addr_info()
|
||||
{
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
explicit addr_info(const char *host, int family, int type)
|
||||
{
|
||||
struct addrinfo hints {};
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = type;
|
||||
if (getaddrinfo(host, nullptr, &hints, &ai) < 0) {
|
||||
freeaddrinfo(ai);
|
||||
ai = nullptr;
|
||||
}
|
||||
}
|
||||
explicit operator bool() const
|
||||
{
|
||||
return ai != nullptr;
|
||||
}
|
||||
struct sockaddr *get_addr(uint16_t port) const {
|
||||
auto *p = (struct sockaddr_in *)ai->ai_addr;
|
||||
p->sin_port = htons(port);
|
||||
return (struct sockaddr *)p;
|
||||
}
|
||||
int get_sock() const
|
||||
{
|
||||
return socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
void tls_client()
|
||||
{
|
||||
const unsigned char message[] = "Hello\n";
|
||||
unsigned char reply[128];
|
||||
TlsSocketClient client;
|
||||
if (!client.connect("tcpbin.com", 4243)) {
|
||||
ESP_LOGE(TAG, "Failed to connect! %d", errno);
|
||||
return;
|
||||
}
|
||||
if (client.write(message, sizeof(message)) < 0) {
|
||||
ESP_LOGE(TAG, "Failed to write!");
|
||||
return;
|
||||
}
|
||||
int len = client.read(reply, sizeof(reply));
|
||||
if (len < 0) {
|
||||
ESP_LOGE(TAG, "Failed to read!");
|
||||
return;
|
||||
}
|
||||
ESP_LOGI(TAG, "Successfully received: %.*s", len, reply);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#if CONFIG_IDF_TARGET_LINUX
|
||||
/**
|
||||
* Linux target: We're already connected, just run the client
|
||||
*/
|
||||
int main()
|
||||
{
|
||||
tls_client();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* ESP32 chipsets: Need to initialize system components
|
||||
* and connect to network
|
||||
*/
|
||||
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_event.h"
|
||||
#include "protocol_examples_common.h"
|
||||
#include "esp_netif.h"
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
tls_client();
|
||||
}
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
Reference in New Issue
Block a user