diff --git a/examples/http_get_ssl/FreeRTOSConfig.h b/examples/http_get_ssl/FreeRTOSConfig.h new file mode 100644 index 0000000..bb56362 --- /dev/null +++ b/examples/http_get_ssl/FreeRTOSConfig.h @@ -0,0 +1,127 @@ +/* + FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd. + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to distribute + >>! a combined work that includes FreeRTOS without being obliged to provide + >>! the source code for proprietary components outside of the FreeRTOS + >>! kernel. + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 ) +#define configTICK_RATE_HZ ( ( portTickType ) 100 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 15 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short )512 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 32 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 + +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 + +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_MUTEXES 1 +#define configUSE_TIMERS 1 + +#if configUSE_TIMERS +#define configTIMER_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define configTIMER_QUEUE_LENGTH (10) +#define configTIMER_TASK_STACK_DEPTH ( ( unsigned short ) 512 ) +#endif + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +/*set the #define for debug info*/ +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/examples/http_get_ssl/Makefile b/examples/http_get_ssl/Makefile new file mode 100644 index 0000000..571d50a --- /dev/null +++ b/examples/http_get_ssl/Makefile @@ -0,0 +1,2 @@ +TARGET=http_get +include ../../common.mk diff --git a/examples/http_get_ssl/main.c b/examples/http_get_ssl/main.c new file mode 100644 index 0000000..01f3fea --- /dev/null +++ b/examples/http_get_ssl/main.c @@ -0,0 +1,216 @@ +#include "espressif/esp_common.h" + +#include "FreeRTOS.h" +#include "task.h" + +#include "lwip/err.h" +#include "lwip/sockets.h" +#include "lwip/sys.h" +#include "lwip/netdb.h" +#include "lwip/dns.h" + +#include "ssl.h" + +#include "espressif/sdk_prototypes.h" + +#define WEB_SERVER "10.10.10.1" +#define WEB_PORT "8000" +#define WEB_URL "https://chainxor.org/" + +/* FILL THESE IN!!!!!!!!!! */ +#define WIFI_SSID "esptest" +#define WIFI_PASS "secret passphrase" + +static void display_cipher(SSL *ssl); +static void display_session_id(SSL *ssl); + +void http_get_task(void *pvParameters) +{ + int successes = 0, failures = 0; + SSL_CTX *ssl_ctx; + uint32_t options = SSL_SERVER_VERIFY_LATER|SSL_DISPLAY_CERTS; + printf("HTTP get task starting...\r\n"); + + printf("free heap = %u\r\n", xPortGetFreeHeapSize()); + if ((ssl_ctx = ssl_ctx_new(options, SSL_DEFAULT_CLNT_SESS)) == NULL) + { + printf("Error: SSL Client context is invalid\n"); + while(1) {} + } + printf("Got SSL context."); + + while(1) { + const struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM, + }; + struct addrinfo *res; + + printf("top of loop, free heap = %u\r\n", xPortGetFreeHeapSize()); + + printf("Running DNS lookup for %s...\r\n", WEB_SERVER); + int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res); + + if(err != 0 || res == NULL) { + printf("DNS lookup failed err=%d res=%p\r\n", err, res); + if(res) + freeaddrinfo(res); + vTaskDelay(1000 / portTICK_RATE_MS); + failures++; + continue; + } + /* Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */ + struct in_addr *addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr; + printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(*addr)); + + int s = socket(res->ai_family, res->ai_socktype, 0); + if(s < 0) { + printf("... Failed to allocate socket.\r\n"); + freeaddrinfo(res); + vTaskDelay(1000 / portTICK_RATE_MS); + failures++; + continue; + } + + printf("... allocated socket\r\n"); + + if(connect(s, res->ai_addr, res->ai_addrlen) != 0) { + close(s); + freeaddrinfo(res); + printf("... socket connect failed.\r\n"); + vTaskDelay(4000 / portTICK_RATE_MS); + failures++; + continue; + } + + printf("... connected. starting TLS session...\r\n"); + freeaddrinfo(res); + + SSL *ssl = ssl_client_new(ssl_ctx, s, NULL, 0); + printf("initial status %p %d\r\n", ssl, ssl_handshake_status(ssl)); + if((err = ssl_handshake_status(ssl)) != SSL_OK) { + ssl_free(ssl); + close(s); + printf("SSL handshake failed. :( %d\r\n", err); + vTaskDelay(4000 / portTICK_RATE_MS); + failures++; + continue; + } + + const char *common_name = ssl_get_cert_dn(ssl, + SSL_X509_CERT_COMMON_NAME); + if (common_name) + { + printf("Common Name:\t\t\t%s\n", common_name); + } + + display_session_id(ssl); + display_cipher(ssl); + + const char *req = + "GET "WEB_URL"\r\n" + "User-Agent: esp-open-rtos/0.1 esp8266\r\n" + "\r\n"; + if (ssl_write(ssl, (uint8_t *)req, strlen(req) + 1) < 0) { + printf("... socket send failed\r\n"); + ssl_free(ssl); + close(s); + vTaskDelay(4000 / portTICK_RATE_MS); + failures++; + continue; + } + printf("... socket send success\r\n"); + + uint8_t *recv_buf; + int r; + do { + r = ssl_read(ssl, &recv_buf); + for(int i = 0; i < r; i++) + printf("%c", recv_buf[i]); + } while(r > 0); + + printf("... done reading from socket. Last read return=%d errno=%d\r\n", r, errno); + if(r != 0) + failures++; + else + successes++; + ssl_free(ssl); + close(s); + printf("successes = %d failures = %d\r\n", successes, failures); + for(int countdown = 10; countdown >= 0; countdown--) { + printf("%d... ", countdown); + vTaskDelay(1000 / portTICK_RATE_MS); + } + printf("\r\nStarting again!\r\n"); + } +} + +void user_init(void) +{ + sdk_uart_div_modify(0, UART_CLK_FREQ / 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + + struct sdk_station_config config = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + }; + + /* required to call wifi_set_opmode before station_set_config */ + sdk_wifi_set_opmode(STATION_MODE); + sdk_wifi_station_set_config(&config); + + xTaskCreate(&http_get_task, (signed char *)"get_task", 2048, NULL, 2, NULL); +} + +/** + * Display what session id we have. + */ +static void display_session_id(SSL *ssl) +{ + int i; + const uint8_t *session_id = ssl_get_session_id(ssl); + int sess_id_size = ssl_get_session_id_size(ssl); + + if (sess_id_size > 0) + { + printf("-----BEGIN SSL SESSION PARAMETERS-----\n"); + for (i = 0; i < sess_id_size; i++) + { + printf("%02x", session_id[i]); + } + + printf("\n-----END SSL SESSION PARAMETERS-----\n"); + } +} + +/** + * Display what cipher we are using + */ +static void display_cipher(SSL *ssl) +{ + printf("CIPHER is "); + switch (ssl_get_cipher_id(ssl)) + { + case SSL_AES128_SHA: + printf("AES128-SHA"); + break; + + case SSL_AES256_SHA: + printf("AES256-SHA"); + break; + + case SSL_RC4_128_SHA: + printf("RC4-SHA"); + break; + + case SSL_RC4_128_MD5: + printf("RC4-MD5"); + break; + + default: + printf("Unknown - %d", ssl_get_cipher_id(ssl)); + break; + } + + printf("\n"); +}