examples: Add esp-ssl example tests server/client

Closes IDF-1156
This commit is contained in:
suren.gabrielyan
2021-02-11 00:46:28 +04:00
committed by Suren Gabrielyan
parent 822cdd81ef
commit 823abfdfd5
24 changed files with 600 additions and 233 deletions

View File

@@ -1,4 +1,4 @@
/* OpenSSL client Example
/* OpenSSL Client Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
@@ -6,172 +6,151 @@
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "openssl_client_example.h"
#include <string.h>
#include "openssl/ssl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_log.h"
#include "protocol_examples_common.h"
#include "lwip/sockets.h"
#include "lwip/netdb.h"
const static char *TAG = "openssl_example";
static const char *TAG = "openssl_example";
static void openssl_example_task(void *p)
static int open_connection(const char *host, char *port)
{
int ret;
SSL_CTX *ctx;
SSL *ssl;
const struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
struct addrinfo * res;
struct in_addr *addr;
int sd;
int err = getaddrinfo(host, port, &hints, &res);
if (err < 0) {
ESP_LOGE(TAG, "getaddrinfo() failed for IPV4 destination address. error: %d", err);
return -1;
}
if (res == 0) {
ESP_LOGE(TAG, "getaddrinfo() did not return any addresses");
return -1;
}
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s", inet_ntoa(*addr));
sd = socket(res->ai_family, res->ai_socktype, 0);
if(sd < 0) {
ESP_LOGE(TAG, "Failed to allocate socket.");
freeaddrinfo(res);
return -1;
}
if (connect(sd, res->ai_addr, res->ai_addrlen) != 0) {
ESP_LOGE(TAG, "Socket connect failed");
return -1;
}
return sd;
}
static SSL_CTX* init_contex(void)
{
#if CONFIG_EXAMPLE_OPENSSL_CLIENT_URI_FROM_STDIN
extern const unsigned char cacert_pem_start[] asm("_binary_ca_crt_start");
extern const unsigned char cacert_pem_end[] asm("_binary_ca_crt_end");
#else
extern const unsigned char cacert_pem_start[] asm("_binary_baidu_ca_crt_start");
extern const unsigned char cacert_pem_end[] asm("_binary_baidu_ca_crt_end");
#endif
const unsigned int cacert_pem_bytes = cacert_pem_end - cacert_pem_start;
const SSL_METHOD *mtd = TLSv1_1_client_method();
SSL_CTX *ctx = SSL_CTX_new(mtd); /* Create new context */
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
X509 *x = d2i_X509(NULL, cacert_pem_start, cacert_pem_bytes);
if(!x) {
ESP_LOGI(TAG,"Loading certs failed \n");
}
SSL_CTX_add_client_CA(ctx, x);
return ctx;
}
static void start_example(const char *host, char *port)
{
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
int sockfd;
struct sockaddr_in sock_addr;
struct hostent *hp;
struct ip4_addr *ip4_addr;
int ret;
int recv_bytes = 0;
char recv_buf[OPENSSL_EXAMPLE_RECV_BUF_LEN];
const char send_data[] = OPENSSL_EXAMPLE_REQUEST;
const int send_bytes = sizeof(send_data);
ESP_LOGI(TAG, "OpenSSL demo thread start OK");
ESP_LOGI(TAG, "get target IP address");
hp = gethostbyname(OPENSSL_EXAMPLE_TARGET_NAME);
if (!hp) {
ESP_LOGI(TAG, "failed");
goto failed1;
}
ESP_LOGI(TAG, "OK");
ip4_addr = (struct ip4_addr *)hp->h_addr;
ESP_LOGI(TAG, IPSTR, IP2STR(ip4_addr));
ESP_LOGI(TAG, "create SSL context ......");
ctx = SSL_CTX_new(TLSv1_1_client_method());
ctx = init_contex();
if (!ctx) {
ESP_LOGI(TAG, "failed");
ESP_LOGE(TAG, "Failed");
goto failed1;
}
ESP_LOGI(TAG, "Trying connect to %s port %s ...", host, port);
sockfd = open_connection(host, port);
if(sockfd < 0) {
ESP_LOGE(TAG,"Failed");
goto failed1;
}
ESP_LOGI(TAG, "OK");
ESP_LOGI(TAG, "create socket ......");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
ESP_LOGI(TAG, "failed");
ESP_LOGI(TAG, "Create SSL obj");
ssl = SSL_new(ctx);
if (!ssl) {
ESP_LOGE(TAG,"Failed");
goto failed2;
}
ESP_LOGI(TAG, "OK");
ESP_LOGI(TAG, "bind socket ......");
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = 0;
sock_addr.sin_port = htons(OPENSSL_EXAMPLE_LOCAL_TCP_PORT);
ret = bind(sockfd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
if (ret) {
ESP_LOGI(TAG, "failed");
goto failed3;
}
ESP_LOGI(TAG, "OK");
ESP_LOGI(TAG, "socket connect to remote %s ......", OPENSSL_EXAMPLE_TARGET_NAME);
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = ip4_addr->addr;
sock_addr.sin_port = htons(OPENSSL_EXAMPLE_TARGET_TCP_PORT);
ret = connect(sockfd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
if (ret) {
ESP_LOGI(TAG, "failed");
goto failed3;
}
ESP_LOGI(TAG, "OK");
ESP_LOGI(TAG, "create SSL ......");
ssl = SSL_new(ctx);
if (!ssl) {
ESP_LOGI(TAG, "failed");
goto failed3;
}
ESP_LOGI(TAG, "OK");
SSL_set_fd(ssl, sockfd);
ESP_LOGI(TAG, "SSL connected to %s port %d ......",
OPENSSL_EXAMPLE_TARGET_NAME, OPENSSL_EXAMPLE_TARGET_TCP_PORT);
ret = SSL_connect(ssl);
if (!ret) {
ESP_LOGI(TAG, "failed " );
goto failed4;
}
ESP_LOGI(TAG, "OK");
ESP_LOGI(TAG, "send https request to %s port %d ......",
OPENSSL_EXAMPLE_TARGET_NAME, OPENSSL_EXAMPLE_TARGET_TCP_PORT);
ret = SSL_write(ssl, send_data, send_bytes);
if (ret <= 0) {
ESP_LOGI(TAG, "failed");
goto failed5;
ESP_LOGE(TAG,"SSL Connection Failed");
goto failed3;
}
ESP_LOGI(TAG, "OK");
do {
ret = SSL_read(ssl, recv_buf, OPENSSL_EXAMPLE_RECV_BUF_LEN - 1);
if (ret <= 0) {
break;
}
recv_buf[ret] = '\0';
recv_bytes += ret;
ESP_LOGI(TAG, "%s", recv_buf);
} while (1);
ESP_LOGI(TAG, "totally read %d bytes data from %s ......", recv_bytes, OPENSSL_EXAMPLE_TARGET_NAME);
failed5:
SSL_shutdown(ssl);
failed4:
ESP_LOGI(TAG,"SSL Connection Succeed");
failed3:
SSL_free(ssl);
ssl = NULL;
failed3:
failed2:
close(sockfd);
sockfd = -1;
failed2:
failed1:
SSL_CTX_free(ctx);
ctx = NULL;
failed1:
vTaskDelete(NULL);
return ;
}
static void openssl_example_client_init(void)
#if CONFIG_EXAMPLE_OPENSSL_CLIENT_URI_FROM_STDIN
static void get_string(char *line, size_t size)
{
int ret;
xTaskHandle openssl_handle;
ret = xTaskCreate(openssl_example_task,
OPENSSL_EXAMPLE_TASK_NAME,
OPENSSL_EXAMPLE_TASK_STACK_WORDS,
NULL,
OPENSSL_EXAMPLE_TASK_PRIORITY,
&openssl_handle);
if (ret != pdPASS) {
ESP_LOGI(TAG, "create thread %s failed", OPENSSL_EXAMPLE_TASK_NAME);
int count = 0;
while (count < size) {
int c = fgetc(stdin);
if (c == '\n') {
line[count] = '\0';
break;
} else if (c > 0 && c < 127) {
line[count] = c;
++count;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
#endif /* CONFIG_EXAMPLE_OPENSSL_CLIENT_URI_FROM_STDIN */
void app_main(void)
{
char host[128] = EXAMPLE_OPENSSL_TARGET_DOMAIN;
char port[32] = EXAMPLE_OPENSSL_TARGET_PORT;
ESP_LOGI(TAG, "[APP] Startup..");
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
@@ -182,5 +161,10 @@ void app_main(void)
*/
ESP_ERROR_CHECK(example_connect());
openssl_example_client_init();
#if CONFIG_EXAMPLE_OPENSSL_CLIENT_URI_FROM_STDIN
char line[256] = "";
get_string(line, sizeof(line));
sscanf(line, "%s %s", host, port);
#endif /* CONFIG_EXAMPLE_OPENSSL_CLIENT_URI_FROM_STDIN */
start_example(host, port);
}