Skip to content

Commit

Permalink
Merge branch 'feature/openssl' into 'master'
Browse files Browse the repository at this point in the history
OpenSSL API examples

add openssl demo

See merge request !198
  • Loading branch information
wujiangang committed Nov 18, 2016
2 parents b092e42 + 2b196b4 commit 8ab4e11
Show file tree
Hide file tree
Showing 16 changed files with 740 additions and 8 deletions.
7 changes: 4 additions & 3 deletions components/openssl/include/internal/ssl_dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,17 @@
#else
#ifdef SSL_PRINT_LOG
#undef SSL_PRINT_LOG
#define SSL_PRINT_LOG(...)
#endif
#define SSL_PRINT_LOG(...)

#ifdef SSL_ERROR_LOG
#undef SSL_ERROR_LOG
#define SSL_ERROR_LOG(...)
#endif
#define SSL_ERROR_LOG(...)
#ifdef SSL_LOCAL_LOG
#undef SSL_LOCAL_LOG
#define SSL_LOCAL_LOG(...)
#endif
#define SSL_LOCAL_LOG(...)
#endif

#if SSL_DEBUG_LOCATION_ENABLE
Expand Down
39 changes: 34 additions & 5 deletions components/openssl/platform/ssl_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ int ssl_pm_new(SSL *ssl)
if (!ssl_pm)
SSL_ERR(ret, failed1, "ssl_mem_zalloc\n");

if (ssl->ctx->read_buffer_len < 2048 ||
ssl->ctx->read_buffer_len > 8192)
return -1;

max_content_len = ssl->ctx->read_buffer_len;

mbedtls_net_init(&ssl_pm->fd);
Expand Down Expand Up @@ -215,6 +211,31 @@ static int ssl_pm_reload_crt(SSL *ssl)
return 0;
}

/*
* Perform the mbedtls SSL handshake instead of mbedtls_ssl_handshake.
* We can add debug here.
*/
LOCAL int mbedtls_handshake( mbedtls_ssl_context *ssl )
{
int ret = 0;

if (ssl == NULL || ssl->conf == NULL)
return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;

while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER)
{
ret = mbedtls_ssl_handshake_step(ssl);

SSL_DEBUG(1, "ssl ret %d state %d heap %d\n",
ret, ssl->state, system_get_free_heap_size());

if (ret != 0)
break;
}

return ret;
}

int ssl_pm_handshake(SSL *ssl)
{
int ret, mbed_ret;
Expand All @@ -224,13 +245,19 @@ int ssl_pm_handshake(SSL *ssl)
if (mbed_ret)
return 0;

SSL_DEBUG(1, "ssl_speed_up_enter ");
ssl_speed_up_enter();
while((mbed_ret = mbedtls_ssl_handshake(&ssl_pm->ssl)) != 0) {
SSL_DEBUG(1, "OK\n");

while((mbed_ret = mbedtls_handshake(&ssl_pm->ssl)) != 0) {
if (mbed_ret != MBEDTLS_ERR_SSL_WANT_READ && mbed_ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
break;
}
}

SSL_DEBUG(1, "ssl_speed_up_exit ");
ssl_speed_up_exit();
SSL_DEBUG(1, "OK\n");

if (!mbed_ret) {
struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm;
Expand Down Expand Up @@ -492,6 +519,7 @@ int x509_pm_load(X509 *x, const unsigned char *buffer, int len)
return 0;

failed2:
mbedtls_x509_crt_free(x509_pm->x509_crt);
ssl_mem_free(x509_pm->x509_crt);
x509_pm->x509_crt = NULL;
failed1:
Expand Down Expand Up @@ -567,6 +595,7 @@ int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len)
return 0;

failed2:
mbedtls_pk_free(pkey_pm->pkey);
ssl_mem_free(pkey_pm->pkey);
pkey_pm->pkey = NULL;
failed1:
Expand Down
9 changes: 9 additions & 0 deletions examples/09_openssl_client/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#

PROJECT_NAME := openssl_client

include $(IDF_PATH)/make/project.mk

16 changes: 16 additions & 0 deletions examples/09_openssl_client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Openssl Example

The Example contains of OpenSSL client demo.

First you should config the project by "make menuconfig":
Example Configuration ->
1. Target Domain : the domain that you want to connect to, and default is "www.baidu.com".
2. Target port number : the port number of the target domain, and default is 443.
3. WIFI SSID : your own WIFI, which is connected to the Internet, and default is "myssid".
4. WIFI Password : WIFI password, and default is "mypassword"

If you want to test the OpenSSL client demo:
1. compile the code and load the firmware
2. open the UART TTY, then you can see it print the context of target domain

See the README.md file in the upper level 'examples' directory for more information about examples.
28 changes: 28 additions & 0 deletions examples/09_openssl_client/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
menu "Example Configuration"

config TARGET_DOMAIN
string "Target Domain"
default "www.baidu.com"
help
Target domain for the example to connect to.

config TARGET_PORT_NUMBER
int "Target port number"
range 0 65535
default 433
help
Target port number for the example to connect to.

config WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.

config WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.

endmenu
3 changes: 3 additions & 0 deletions examples/09_openssl_client/main/component.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#
# Main Makefile. This is basically the same as a component makefile.
#
225 changes: 225 additions & 0 deletions examples/09_openssl_client/main/openssl_client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/* OpenSSL client Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/

#include "openssl_client.h"

#include <string.h>

#include "openssl/ssl.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"

#include "nvs_flash.h"

#include "lwip/sockets.h"
#include "lwip/netdb.h"

static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
const static int CONNECTED_BIT = BIT0;

const static char *TAG = "Openssl_demo";

void openssl_demo_thread(void *p)
{
int ret;
SSL_CTX *ctx;
SSL *ssl;
int socket;
struct sockaddr_in sock_addr;
struct hostent *hp;
struct ip4_addr *ip4_addr;

int recv_bytes = 0;
char recv_buf[OPENSSL_DEMO_RECV_BUF_LEN];

const char send_data[] = OPENSSL_DEMO_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_DEMO_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());
if (!ctx) {
ESP_LOGI(TAG, "failed");
goto failed1;
}
ESP_LOGI(TAG, "OK");

ESP_LOGI(TAG, "create socket ......");
socket = socket(AF_INET, SOCK_STREAM, 0);
if (socket < 0) {
ESP_LOGI(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_DEMO_LOCAL_TCP_PORT);
ret = bind(socket, (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_DEMO_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_DEMO_TARGET_TCP_PORT);
ret = connect(socket, (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, socket);

ESP_LOGI(TAG, "SSL connected to %s port %d ......",
OPENSSL_DEMO_TARGET_NAME, OPENSSL_DEMO_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_DEMO_TARGET_NAME, OPENSSL_DEMO_TARGET_TCP_PORT);
ret = SSL_write(ssl, send_data, send_bytes);
if (ret <= 0) {
ESP_LOGI(TAG, "failed");
goto failed5;
}
ESP_LOGI(TAG, "OK");

do {
ret = SSL_read(ssl, recv_buf, OPENSSL_DEMO_RECV_BUF_LEN - 1);
if (ret <= 0) {
break;
}
recv_bytes += ret;
ESP_LOGI(TAG, "%s", recv_buf);
} while (1);

ESP_LOGI(TAG, "totaly read %d bytes data from %s ......", recv_bytes, OPENSSL_DEMO_TARGET_NAME);

failed5:
SSL_shutdown(ssl);
failed4:
SSL_free(ssl);
ssl = NULL;
failed3:
close(socket);
socket = -1;
failed2:
SSL_CTX_free(ctx);
ctx = NULL;
failed1:
vTaskDelete(NULL);
return ;
}

static void openssl_client_init(void)
{
int ret;
xTaskHandle openssl_handle;

ret = xTaskCreate(openssl_demo_thread,
OPENSSL_DEMO_THREAD_NAME,
OPENSSL_DEMO_THREAD_STACK_WORDS,
NULL,
OPENSSL_DEMO_THREAD_PRORIOTY,
&openssl_handle);

if (ret != pdPASS) {
ESP_LOGI(TAG, "create thread %s failed", OPENSSL_DEMO_THREAD_NAME);
}
}

static esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
{
switch(event->event_id) {
case SYSTEM_EVENT_STA_START:
esp_wifi_connect();
break;
case SYSTEM_EVENT_STA_GOT_IP:
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
openssl_client_init();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
/* This is a workaround as ESP32 WiFi libs don't currently
auto-reassociate. */
esp_wifi_connect();
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
break;
default:
break;
}
return ESP_OK;
}

static void wifi_conn_init(void)
{
tcpip_adapter_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
ESP_LOGI(TAG, "start the WIFI SSID:[%s] password:[%s]\n", EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS);
ESP_ERROR_CHECK( esp_wifi_start() );
}

void app_main(void)
{
nvs_flash_init();
wifi_conn_init();
}

0 comments on commit 8ab4e11

Please sign in to comment.