diff --git a/components/ssl/mbedtls/port/include/esp_config.h b/components/ssl/mbedtls/port/include/esp_config.h index de27badb..ad3c9462 100644 --- a/components/ssl/mbedtls/port/include/esp_config.h +++ b/components/ssl/mbedtls/port/include/esp_config.h @@ -2766,8 +2766,7 @@ //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ /* SSL options */ -extern unsigned int max_content_len; -#define MBEDTLS_SSL_MAX_CONTENT_LEN max_content_len /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 8192 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ //#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ diff --git a/examples/protocols/https_mbedtls/Makefile b/examples/protocols/https_mbedtls/Makefile new file mode 100644 index 00000000..a6777c41 --- /dev/null +++ b/examples/protocols/https_mbedtls/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := https-mbedtls + +include $(IDF_PATH)/make/project.mk \ No newline at end of file diff --git a/examples/protocols/https_mbedtls/main/Kconfig.projbuild b/examples/protocols/https_mbedtls/main/Kconfig.projbuild new file mode 100644 index 00000000..92a75195 --- /dev/null +++ b/examples/protocols/https_mbedtls/main/Kconfig.projbuild @@ -0,0 +1,17 @@ +menu "Example Configuration" + +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. + + Can be left blank if the network has no security set. + +endmenu diff --git a/examples/protocols/https_mbedtls/main/component.mk b/examples/protocols/https_mbedtls/main/component.mk new file mode 100644 index 00000000..12acf9fa --- /dev/null +++ b/examples/protocols/https_mbedtls/main/component.mk @@ -0,0 +1,5 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) +COMPONENT_EMBED_TXTFILES := server_root_cert.pem diff --git a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c new file mode 100644 index 00000000..b145a25d --- /dev/null +++ b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c @@ -0,0 +1,342 @@ +/* mbedtls 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 "sdkconfig.h" + +#include "esp_misc.h" +#include "esp_sta.h" +#include "esp_system.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include +#include + +#include "mbedtls/platform.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/certs.h" + +extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); +extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); + +#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID +#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD + +/* Constants that aren't configurable in menuconfig */ +#define WEB_SERVER "www.howsmyssl.com" +#define WEB_PORT "443" +#define WEB_URL "https://www.howsmyssl.com/a/check" + +static const char* REQUEST = "GET " WEB_URL " HTTP/1.0\r\n" + "Host: "WEB_SERVER"\r\n" + "User-Agent: esp-idf/1.0 espressif\r\n" + "\r\n"; + +#define HTTPS_MBEDTLS_THREAD_NAME "https_mbedtls" +#define HTTPS_MBEDTLS_THREAD_STACK_WORDS 2048 +#define HTTPS_MBEDTLS_THREAD_PRORIOTY 6 + +#define HTTPS_MBEDTLS_SNTP_SERVERS "pool.ntp.org" + +static void https_get_task() +{ + char buf[512]; + int ret, flags, len; + + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ssl_context ssl; + mbedtls_x509_crt cacert; + mbedtls_ssl_config conf; + mbedtls_net_context server_fd; + + uint32_t current_timestamp = 0; + /*enable sntp for sync the time*/ + sntp_setoperatingmode(0); + sntp_setservername(0, HTTPS_MBEDTLS_SNTP_SERVERS); + sntp_init(); + + do { + current_timestamp = sntp_get_current_timestamp(); + vTaskDelay(500 / portTICK_RATE_MS); + } while (current_timestamp == 0); + + mbedtls_ssl_init(&ssl); + mbedtls_x509_crt_init(&cacert); + mbedtls_ctr_drbg_init(&ctr_drbg); + printf("Seeding the random number generator\n"); + + mbedtls_ssl_config_init(&conf); + + mbedtls_entropy_init(&entropy); + + if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + NULL, 0)) != 0) { + printf("mbedtls_ctr_drbg_seed returned %d\n", ret); + vTaskDelete(NULL); + return; + } + + printf("Loading the CA root certificate...\n"); + + ret = mbedtls_x509_crt_parse(&cacert, server_root_cert_pem_start, server_root_cert_pem_end - server_root_cert_pem_start); + + if (ret < 0) { + printf("mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); + vTaskDelete(NULL); + return; + } + + printf("Setting hostname for TLS session...\n"); + + /* Hostname set here should match CN in server certificate */ + if ((ret = mbedtls_ssl_set_hostname(&ssl, WEB_SERVER)) != 0) { + printf("mbedtls_ssl_set_hostname returned -0x%x", -ret); + vTaskDelete(NULL); + return; + } + + printf("Setting up the SSL/TLS structure...\n"); + + if ((ret = mbedtls_ssl_config_defaults(&conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { + printf("mbedtls_ssl_config_defaults returned %d", ret); + goto exit; + } + + mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); + mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); + mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); + + if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { + printf("mbedtls_ssl_setup returned -0x%x\n\n", -ret); + goto exit; + } + + while (1) { + mbedtls_net_init(&server_fd); + + printf("Connecting to %s:%s...\n", WEB_SERVER, WEB_PORT); + + if ((ret = mbedtls_net_connect(&server_fd, WEB_SERVER, + WEB_PORT, MBEDTLS_NET_PROTO_TCP)) != 0) { + printf("mbedtls_net_connect returned -%x\n", -ret); + goto exit; + } + + printf("Connected.\n"); + + mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL); + + printf("Performing the SSL/TLS handshake...\n"); + + while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { + printf("mbedtls_ssl_handshake returned -0x%x\n", -ret); + goto exit; + } + } + + printf("Verifying peer X.509 certificate...\n"); + + if ((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0) { + /* In real life, we probably want to close connection if ret != 0 */ + printf("Failed to verify peer certificate!\n"); + bzero(buf, sizeof(buf)); + mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags); + printf("verification info: %s\n", buf); + } else { + printf("Certificate verified.\n"); + } + + printf("Cipher suite is %s\n", mbedtls_ssl_get_ciphersuite(&ssl)); + + printf("Writing HTTP request...\n"); + + size_t written_bytes = 0; + + do { + ret = mbedtls_ssl_write(&ssl, + (const unsigned char*)REQUEST + written_bytes, + strlen(REQUEST) - written_bytes); + + if (ret >= 0) { + printf("%d bytes written\n", ret); + written_bytes += ret; + } else if (ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_WANT_READ) { + printf("mbedtls_ssl_write returned -0x%x\n", -ret); + goto exit; + } + } while (written_bytes < strlen(REQUEST)); + + printf("Reading HTTP response...\n"); + + do { + len = sizeof(buf) - 1; + bzero(buf, sizeof(buf)); + ret = mbedtls_ssl_read(&ssl, (unsigned char*)buf, len); + + if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { + continue; + } + + if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + ret = 0; + break; + } + + if (ret < 0) { + printf("mbedtls_ssl_read returned -0x%x\n", -ret); + break; + } + + if (ret == 0) { + printf("\nconnection closed\n"); + break; + } + + len = ret; + + /* Print response directly to stdout as it is read */ + for (int i = 0; i < len; i++) { + printf("%c", buf[i]); + } + } while (1); + + mbedtls_ssl_close_notify(&ssl); + +exit: + mbedtls_ssl_session_reset(&ssl); + mbedtls_net_free(&server_fd); + + if (ret != 0) { + mbedtls_strerror(ret, buf, 100); + printf("Last error was: -0x%x - %s\n", -ret, buf); + } + + printf("\n"); // JSON output doesn't have a newline at end + + static int request_count; + printf("Completed %d requests\n", ++request_count); + + for (int countdown = 10; countdown >= 0; countdown--) { + printf("%d...\n", countdown); + vTaskDelay(1000 / portTICK_RATE_MS); + } + + printf("Starting again!\n"); + } +} + +void user_conn_init(void) +{ + int32_t ret; + + ret = xTaskCreate(https_get_task, + HTTPS_MBEDTLS_THREAD_NAME, + HTTPS_MBEDTLS_THREAD_STACK_WORDS, + NULL, + HTTPS_MBEDTLS_THREAD_PRORIOTY, + NULL); + + if (ret != pdPASS) { + printf("create thread %s failed\n", HTTPS_MBEDTLS_THREAD_NAME); + return ; + } +} + +void wifi_event_handler_cb(System_Event_t* event) +{ + if (event == NULL) { + return; + } + + switch (event->event_id) { + case EVENT_STAMODE_GOT_IP: + printf("sta got ip\n"); + user_conn_init(); + break; + + default: + break; + } +} + +/****************************************************************************** + * FunctionName : user_rf_cal_sector_set + * Description : SDK just reversed 4 sectors, used for rf init data and paramters. + * We add this function to force users to set rf cal sector, since + * we don't know which sector is free in user's application. + * sector map for last several sectors : ABCCC + * A : rf cal/* Websocket example + * B : rf init data + * C : sdk parameters + * Parameters : none + * Returns : rf cal sector +*******************************************************************************/ +uint32_t user_rf_cal_sector_set(void) +{ + flash_size_map size_map = system_get_flash_size_map(); + uint32_t rf_cal_sec = 0; + + switch (size_map) { + case FLASH_SIZE_4M_MAP_256_256: + rf_cal_sec = 128 - 5; + break; + + case FLASH_SIZE_8M_MAP_512_512: + rf_cal_sec = 256 - 5; + break; + + case FLASH_SIZE_16M_MAP_512_512: + case FLASH_SIZE_16M_MAP_1024_1024: + rf_cal_sec = 512 - 5; + break; + + case FLASH_SIZE_32M_MAP_512_512: + case FLASH_SIZE_32M_MAP_1024_1024: + rf_cal_sec = 1024 - 5; + break; + + case FLASH_SIZE_64M_MAP_1024_1024: + rf_cal_sec = 2048 - 5; + break; + + case FLASH_SIZE_128M_MAP_1024_1024: + rf_cal_sec = 4096 - 5; + break; + + default: + rf_cal_sec = 0; + break; + } + + return rf_cal_sec; +} + +void user_init() +{ + wifi_set_opmode(STATION_MODE); + + // set AP parameter + struct station_config config; + bzero(&config, sizeof(struct station_config)); + sprintf(config.ssid, CONFIG_WIFI_SSID); + sprintf(config.password, CONFIG_WIFI_PASSWORD); + wifi_station_set_config(&config); + + wifi_set_event_handler_cb(wifi_event_handler_cb); +} diff --git a/examples/protocols/https_mbedtls/main/server_root_cert.pem b/examples/protocols/https_mbedtls/main/server_root_cert.pem new file mode 100644 index 00000000..0002462c --- /dev/null +++ b/examples/protocols/https_mbedtls/main/server_root_cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow +SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT +GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF +q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 +SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 +Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA +a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj +/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG +CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv +bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k +c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw +VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC +ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz +MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu +Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF +AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo +uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ +wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu +X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG +PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 +KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== +-----END CERTIFICATE-----