diff --git a/examples/Certificate/Certificate.ino b/examples/Certificate/Certificate.ino new file mode 100644 index 0000000..4117136 --- /dev/null +++ b/examples/Certificate/Certificate.ino @@ -0,0 +1,192 @@ +/** + * This example shows how to connect to server via https and verify the root certificate using the SSL client. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +// Baltimore CyberTrust Root +// Expired on Tue May 13 2025 +const char rootCA[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n" + "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n" + "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n" + "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n" + "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n" + "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n" + "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n" + "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n" + "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n" + "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n" + "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n" + "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n" + "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n" + "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n" + "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n" + "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n" + "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n" + "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n" + "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" + "-----END CERTIFICATE-----\n"; + +ESP_SSLClient ssl_client; + +// EthernetClient basic_client; +// GSMClient basic_client; +WiFiClient basic_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + Serial.begin(115200); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + +// The valid time is required for server certificate verification. +#if defined(ESP8266) || defined(ESP32) && !defined(ARDUINO_NANO_RP2040_CONNECT) + + configTime(0, 0, "pool.ntp.org", "time.nist.gov"); + while (time(nullptr) < ESP_SSLCLIENT_VALID_TIMESTAMP) + { + delay(100); + } + + // If verification time was not set via this function, the device system time will be used + // ssl_client.setX509Time(time(nullptr)); + +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) + + configTime(10000, 0, "pool.ntp.org", "time.nist.gov"); + while (time(nullptr) < ESP_SSLCLIENT_VALID_TIMESTAMP) + { + delay(100); + } + + // If verification time was not set via this function, the device system time will be used + // ssl_client.setX509Time(time(nullptr)); + +#elif __has_include() || __has_include() + time_t ts = 0; + do + { + ts = WiFi.getTime(); + delay(100); + } while (ts < ESP_SSLCLIENT_VALID_TIMESTAMP); + + // The verification time setting is required because the device system time i.e. time(nullptr) is not available in this case. + ssl_client.setX509Time(ts); +#endif + + // Set the server certificate, intermediate cerificate or root certificate + ssl_client.setCACert(rootCA); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); +} + +void loop() +{ + Serial.println("---------------------------------"); + Serial.print("Connecting to server..."); + + String payload = "{\"title\":\"hello\"}"; + + if (ssl_client.connect("reqres.in", 443)) + { + Serial.println(" ok"); + Serial.println("Send POST request..."); + ssl_client.print("POST /api/users HTTP/1.1\r\n"); + ssl_client.print("Host: reqres.in\r\n"); + ssl_client.print("Content-Type: application/json\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(payload.length()); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + + Serial.print("Read response..."); + + unsigned long ms = millis(); + while (!ssl_client.available() && millis() - ms < 3000) + { + delay(0); + } + Serial.println(); + while (ssl_client.available()) + { + Serial.print((char)ssl_client.read()); + } + Serial.println(); + } + else + Serial.println(" failed\n"); + + ssl_client.stop(); + + Serial.println(); + + delay(5000); +} \ No newline at end of file diff --git a/examples/Custom_Secure_Port/Custom_Secure_Port.ino b/examples/Custom_Secure_Port/Custom_Secure_Port.ino new file mode 100644 index 0000000..b66c6db --- /dev/null +++ b/examples/Custom_Secure_Port/Custom_Secure_Port.ino @@ -0,0 +1,149 @@ +/** + * This example shows how to connect to server via custom secure port. + * + * The standard secure ports as listed here are supported by this library https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers. + * + * If the port you want to connect with SSL/TLS is not in the list, you can begin the connection in the plain text mode first and upgrade later. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +ESP_SSLClient ssl_client; + +// EthernetClient basic_client; +// GSMClient basic_client; +WiFiClient basic_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + Serial.begin(115200); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client to use in non-secure mode. + ssl_client.setClient(&basic_client, false /* set enable SSL option to false */); +} + +void loop() +{ + Serial.println("---------------------------------"); + + Serial.print("Connecting to server via HTTP..."); + + String payload = "{\"title\":\"hello\"}"; + + String server = "your_server.com"; // The server to connect. + uint16_t port = 5443; // The port to connect. + + if (ssl_client.connect(server.c_str(), port)) + { + Serial.println(" ok"); + + Serial.print("Upgrade to HTTPS..."); + if (!ssl_client.connectSSL()) + { + Serial.println(" failed\r\n"); + return; + } + + Serial.println(" ok"); + + Serial.println("Send GET request..."); + ssl_client.print("GET / HTTP/1.1\r\n"); + ssl_client.print("Host: "); + ssl_client.print(server); + ssl_client.print("\r\n"); + ssl_client.print("Content-Type: application/json\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(payload.length()); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + + Serial.print("Read response..."); + unsigned long ms = millis(); + while (!ssl_client.available() && millis() - ms < 3000) + { + delay(0); + } + Serial.println(); + while (ssl_client.available()) + { + Serial.print((char)ssl_client.read()); + } + Serial.println(); + } + else + Serial.println(" failed\n"); + + ssl_client.stop(); + + Serial.println(); + + delay(5000); +} \ No newline at end of file diff --git a/examples/Ethernet/Ethernet.ino b/examples/Ethernet/Ethernet.ino new file mode 100644 index 0000000..5ffa0f7 --- /dev/null +++ b/examples/Ethernet/Ethernet.ino @@ -0,0 +1,137 @@ +/** + * This example shows how to connect to server using W5500, ESP32 and SSL Client. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ + +#include +#include + +#include + +#define WIZNET_RESET_PIN 26 // Connect W5500 Reset pin to GPIO 26 of ESP32 +#define WIZNET_CS_PIN 5 // Connect W5500 CS pin to GPIO 5 of ESP32 +#define WIZNET_MISO_PIN 19 // Connect W5500 MISO pin to GPIO 19 of ESP32 +#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 of ESP32 +#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 of ESP32 + +ESP_SSLClient ssl_client; + +EthernetClient basic_client; + +uint8_t Eth_MAC[] = {0x02, 0xF0, 0x0D, 0xBE, 0xEF, 0x01}; + +void ResetEthernet() +{ + Serial.println("Resetting WIZnet W5500 Ethernet Board... "); + pinMode(WIZNET_RESET_PIN, OUTPUT); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); + digitalWrite(WIZNET_RESET_PIN, LOW); + delay(50); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); +} + +void networkConnection() +{ + + Ethernet.init(WIZNET_CS_PIN); + + ResetEthernet(); + + Serial.println("Starting Ethernet connection..."); + Ethernet.begin(Eth_MAC); + + unsigned long to = millis(); + + while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) + { + delay(100); + } + + if (Ethernet.linkStatus() == LinkON) + { + Serial.print("Connected with IP "); + Serial.println(Ethernet.localIP()); + } + else + { + Serial.println("Can't connect"); + } +} + +void setup() +{ + Serial.begin(115200); + + networkConnection(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); +} + +void loop() +{ + Serial.println("---------------------------------"); + Serial.print("Connecting to server..."); + + String payload = "{\"title\":\"hello\"}"; + + if (ssl_client.connect("reqres.in", 443)) + { + Serial.println(" ok"); + Serial.println("Send POST request..."); + ssl_client.print("POST /api/users HTTP/1.1\r\n"); + ssl_client.print("Host: reqres.in\r\n"); + ssl_client.print("Content-Type: application/json\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(payload.length()); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + + Serial.print("Read response..."); + + unsigned long ms = millis(); + while (!ssl_client.available() && millis() - ms < 3000) + { + delay(0); + } + Serial.println(); + while (ssl_client.available()) + { + Serial.print((char)ssl_client.read()); + } + Serial.println(); + } + else + Serial.println(" failed\n"); + + ssl_client.stop(); + + Serial.println(); + + delay(5000); +} \ No newline at end of file diff --git a/examples/GSM/GSM.ino b/examples/GSM/GSM.ino new file mode 100644 index 0000000..7621789 --- /dev/null +++ b/examples/GSM/GSM.ino @@ -0,0 +1,264 @@ +/** + * This example shows how to connect to server using LilyGo TTGO T-A7670X and SSL Client. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ + +#define TINY_GSM_MODEM_SIM7600 // SIMA7670 Compatible with SIM7600 AT instructions + +// Set serial for debug console (to the Serial Monitor, default speed 115200) +#define SerialMon Serial + +// Set serial for AT commands (to the module) +// Use Hardware Serial on Mega, Leonardo, Micro +#define SerialAT Serial1 + +// See all AT commands, if wanted +// #define DUMP_AT_COMMANDS + +// Define the serial console for debug prints, if needed +#define TINY_GSM_DEBUG SerialMon + +#define TINY_GSM_USE_GPRS true +#define TINY_GSM_USE_WIFI false + +// set GSM PIN, if any +#define GSM_PIN "" + +// Your GPRS credentials, if any +const char apn[] = "YourAPN"; +const char gprsUser[] = ""; +const char gprsPass[] = ""; + +#include + +#include + +#ifdef DUMP_AT_COMMANDS +#include +StreamDebugger debugger(SerialAT, SerialMon); +TinyGsm modem(debugger); +#else +TinyGsm modem(SerialAT); +#endif + +TinyGsmClient basic_client(modem); + +ESP_SSLClient ssl_client; + +#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds +#define TIME_TO_SLEEP 600 // Time ESP32 will go to sleep (in seconds) + +#define UART_BAUD 115200 +#define PIN_DTR 25 +#define PIN_TX 26 +#define PIN_RX 27 +#define PWR_PIN 4 +#define BAT_ADC 35 +#define BAT_EN 12 +#define PIN_RI 33 +#define PIN_DTR 25 +#define RESET 5 + +#define SD_MISO 2 +#define SD_MOSI 15 +#define SD_SCLK 14 +#define SD_CS 13 + +void setup() +{ + // Set console baud rate + SerialMon.begin(115200); + delay(10); + pinMode(BAT_EN, OUTPUT); + digitalWrite(BAT_EN, HIGH); + + // A7670 Reset + pinMode(RESET, OUTPUT); + digitalWrite(RESET, LOW); + delay(100); + digitalWrite(RESET, HIGH); + delay(3000); + digitalWrite(RESET, LOW); + + pinMode(PWR_PIN, OUTPUT); + digitalWrite(PWR_PIN, LOW); + delay(100); + digitalWrite(PWR_PIN, HIGH); + delay(1000); + digitalWrite(PWR_PIN, LOW); + + DBG("Wait..."); + + delay(3000); + + SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX); + + // Restart takes quite some time + // To skip it, call init() instead of restart() + DBG("Initializing modem..."); + if (!modem.init()) + { + DBG("Failed to restart modem, delaying 10s and retrying"); + return; + } + + /* + 2 Automatic + 13 GSM Only + 14 WCDMA Only + 38 LTE Only + */ + modem.setNetworkMode(38); + if (modem.waitResponse(10000L) != 1) + { + DBG(" setNetworkMode faill"); + return; + } +} + +void loop() +{ + // Restart takes quite some time + // To skip it, call init() instead of restart() + /* DBG("Initializing modem..."); + if (!modem.restart()) { + DBG("Failed to restart modem, delaying 10s and retrying"); + return; + }*/ + + String name = modem.getModemName(); + DBG("Modem Name:", name); + + String modemInfo = modem.getModemInfo(); + DBG("Modem Info:", modemInfo); + +#if TINY_GSM_USE_GPRS + // Unlock your SIM card with a PIN if needed + if (GSM_PIN && modem.getSimStatus() != 3) + { + modem.simUnlock(GSM_PIN); + } +#endif + +#if TINY_GSM_USE_WIFI + // Wifi connection parameters must be set before waiting for the network + SerialMon.print(F("Setting SSID/password...")); + if (!modem.networkConnect(wifiSSID, wifiPass)) + { + SerialMon.println(" fail"); + delay(10000); + return; + } + SerialMon.println(" success"); +#endif + +#if TINY_GSM_USE_GPRS && defined TINY_GSM_MODEM_XBEE + // The XBee must run the gprsConnect function BEFORE waiting for network! + modem.gprsConnect(apn, gprsUser, gprsPass); +#endif + + SerialMon.print("Waiting for network..."); + if (!modem.waitForNetwork()) + { + SerialMon.println(" fail"); + delay(10000); + return; + } + SerialMon.println(" success"); + + if (modem.isNetworkConnected()) + { + SerialMon.println("Network connected"); + } + +#if TINY_GSM_USE_GPRS + // GPRS connection parameters are usually set after network registration + SerialMon.print(F("Connecting to ")); + SerialMon.print(apn); + if (!modem.gprsConnect(apn, gprsUser, gprsPass)) + { + SerialMon.println(" fail"); + delay(10000); + return; + } + SerialMon.println(" success"); + + if (modem.isGprsConnected()) + { + SerialMon.println("GPRS connected"); + } +#endif + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); + + Serial.println("---------------------------------"); + Serial.print("Connecting to server..."); + + String payload = "{\"title\":\"hello\"}"; + + if (ssl_client.connect("reqres.in", 443)) + { + Serial.println(" ok"); + Serial.println("Send POST request..."); + ssl_client.print("POST /api/users HTTP/1.1\r\n"); + ssl_client.print("Host: reqres.in\r\n"); + ssl_client.print("Content-Type: application/json\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(payload.length()); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + + Serial.print("Read response..."); + + unsigned long ms = millis(); + while (!ssl_client.available() && millis() - ms < 3000) + { + delay(0); + } + Serial.println(); + while (ssl_client.available()) + { + Serial.print((char)ssl_client.read()); + } + Serial.println(); + } + else + Serial.println(" failed\n"); + + ssl_client.stop(); + + Serial.println(); + + modem.gprsDisconnect(); + SerialMon.println(F("GPRS disconnected")); + + // Do nothing forevermore + while (true) + { + delay(1000); + } +} \ No newline at end of file diff --git a/examples/HTTP_Upgrade/HTTP_Upgrade.ino b/examples/HTTP_Upgrade/HTTP_Upgrade.ino new file mode 100644 index 0000000..9610f80 --- /dev/null +++ b/examples/HTTP_Upgrade/HTTP_Upgrade.ino @@ -0,0 +1,142 @@ +/** + * This example shows how to upgrade from http connection to https connection. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +ESP_SSLClient ssl_client; + +// EthernetClient basic_client; +// GSMClient basic_client; +WiFiClient basic_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + Serial.begin(115200); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client, false /* set enable SSL option to false */); +} + +void loop() +{ + Serial.println("---------------------------------"); + + Serial.print("Connecting to server via HTTP..."); + + String payload = "{\"title\":\"hello\"}"; + + if (ssl_client.connect("reqres.in", 443)) + { + Serial.println(" ok"); + + Serial.print("Upgrade to HTTPS..."); + if (!ssl_client.connectSSL()) + { + Serial.println(" failed\r\n"); + return; + } + + Serial.println(" ok"); + + Serial.println("Send POST request..."); + ssl_client.print("POST /api/users HTTP/1.1\r\n"); + ssl_client.print("Host: reqres.in\r\n"); + ssl_client.print("Content-Type: application/json\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(payload.length()); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + + Serial.print("Read response..."); + unsigned long ms = millis(); + while (!ssl_client.available() && millis() - ms < 3000) + { + delay(0); + } + Serial.println(); + while (ssl_client.available()) + { + Serial.print((char)ssl_client.read()); + } + Serial.println(); + } + else + Serial.println(" failed\n"); + + ssl_client.stop(); + + Serial.println(); + + delay(5000); +} \ No newline at end of file diff --git a/examples/HTTPs/https.ino b/examples/HTTPs/https.ino new file mode 100644 index 0000000..1ff0a40 --- /dev/null +++ b/examples/HTTPs/https.ino @@ -0,0 +1,133 @@ +/** + * This example shows how to connect to server via https using the SSL client. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +ESP_SSLClient ssl_client; + +// EthernetClient basic_client; +// GSMClient basic_client; +WiFiClient basic_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + Serial.begin(115200); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); +} + +void loop() +{ + Serial.println("---------------------------------"); + Serial.print("Connecting to server..."); + + String payload = "{\"title\":\"hello\"}"; + + if (ssl_client.connect("reqres.in", 443)) + { + Serial.println(" ok"); + Serial.println("Send POST request..."); + ssl_client.print("POST /api/users HTTP/1.1\r\n"); + ssl_client.print("Host: reqres.in\r\n"); + ssl_client.print("Content-Type: application/json\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(payload.length()); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + + Serial.print("Read response..."); + + unsigned long ms = millis(); + while (!ssl_client.available() && millis() - ms < 3000) + { + delay(0); + } + Serial.println(); + while (ssl_client.available()) + { + Serial.print((char)ssl_client.read()); + } + Serial.println(); + } + else + Serial.println(" failed\n"); + + ssl_client.stop(); + + Serial.println(); + + delay(5000); +} \ No newline at end of file diff --git a/examples/MQTT/MQTT.ino b/examples/MQTT/MQTT.ino new file mode 100644 index 0000000..8fa949e --- /dev/null +++ b/examples/MQTT/MQTT.ino @@ -0,0 +1,181 @@ +/** + * This example shows how to connect to MQTT server via secure port using the SSL client. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +// https://github.com/arduino-libraries/ArduinoMqttClient +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +ESP_SSLClient ssl_client; + +// EthernetClient basic_client; +// GSMClient basic_client; +WiFiClient basic_client; + +MqttClient mqttClient(ssl_client); + +unsigned long lastMillis = 0; + +int count = 0; + +const char broker[] = "test.mosquitto.org"; +int port = 8883; +const char topic[] = "arduino/simple"; + +const long interval = 3000; +unsigned long previousMillis = 0; +bool mqttReady = false; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); + + Serial.print("Attempting to connect to the MQTT broker over ssl: "); + Serial.println(broker); + + if (!mqttClient.connect(broker, port)) + { + Serial.print("MQTT connection failed! Error code = "); + Serial.println(mqttClient.connectError()); + return; + } + + Serial.println("You're connected to the MQTT broker!"); + Serial.println(); + + Serial.print("Subscribing to topic: "); + Serial.println(topic); + Serial.println(); + + // subscribe to a topic + mqttClient.subscribe(topic); + + // topics can be unsubscribed using: + // mqttClient.unsubscribe(topic); + + Serial.print("Waiting for messages on topic: "); + Serial.println(topic); + Serial.println(); + mqttReady = true; +} + +void loop() +{ + + if (!mqttReady) + return; + + int messageSize = mqttClient.parseMessage(); + if (messageSize) + { + // we received a message, print out the topic and contents + Serial.print("Received a message with topic '"); + Serial.print(mqttClient.messageTopic()); + Serial.print("', length "); + Serial.print(messageSize); + Serial.println(" bytes:"); + + // use the Stream interface to print the contents + while (mqttClient.available()) + { + Serial.print((char)mqttClient.read()); + } + Serial.println(); + + Serial.println(); + } + + mqttClient.poll(); + + if (millis() - lastMillis > interval) + { + lastMillis = millis(); + + Serial.print("Sending message to topic: "); + + Serial.println(topic); + + // send message, the Print interface can be used to set the message contents + mqttClient.beginMessage(topic); + + mqttClient.print(count); + + mqttClient.endMessage(); + count++; + } +} \ No newline at end of file diff --git a/examples/Public_Key/Public_Key.ino b/examples/Public_Key/Public_Key.ino new file mode 100644 index 0000000..98eec8b --- /dev/null +++ b/examples/Public_Key/Public_Key.ino @@ -0,0 +1,75 @@ +/** + * This example shows how to parse public key. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ +#include + +#include + +const char public_key[] PROGMEM = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnD6sFeCJf9bR7PH/YisP\n" + "wCePMUltELq/hp/Dm409XU/yEbgBTI/wMUnH+2juOTYeCirOB10bc/QrFVhaLV3g\n" + "HWyvSL+Wv0ufdWeZiLXAnICNddiJCQvOU+5seNUoPw4QKvFAQgZLogsjWm2uajJS\n" + "nSGskVCt48gaWVrIiO4OQZVkSTxXrUNknenXJ9b2bXam/Bt1ya1E1t1/b/ITZ/03\n" + "WQjfGwXgctqYytvAHC3v541s9o53J2uWn/pOBJc2058Ad5WyzqPRHzA1gbl+XinK\n" + "s85X5U5PAwJiVCsSyCFkNGwJmmuCPtrHipwZi5ax5jfrb71Plilj2VOXdrR2zU7F\n" + "OQIDAQAB\n" + "-----END PUBLIC KEY-----\n"; + +ESP_SSLClient ssl_client; + +void setup() +{ + + Serial.begin(115200); + delay(5000); + + PublicKey pk; + pk.parse(public_key); + + Serial.println(); + + Serial.println("Parse key..."); + + if (pk.isRSA()) + { + Serial.println("RSA key detected."); + + Serial.println("Modulus..."); + + for (int i = 0; i < (int)pk.getRSA()->nlen; i++) + { + Serial.print(((const char *)pk.getRSA()->n)[i], HEX); + Serial.print(" "); + } + + Serial.println(); + } + else if (pk.isEC()) + { + Serial.println("ECC key detected."); + Serial.println("Curve point..."); + + for (int i = 0; i < (int)pk.getEC()->qlen; i++) + { + Serial.print(((const char *)pk.getEC()->q)[i], HEX); + Serial.print(" "); + } + + Serial.println(); + } + else + { + Serial.println("Unknown key"); + } +} + +void loop() +{ +} \ No newline at end of file diff --git a/examples/SSE/SSE.ino b/examples/SSE/SSE.ino new file mode 100644 index 0000000..ec5f285 --- /dev/null +++ b/examples/SSE/SSE.ino @@ -0,0 +1,137 @@ +/** + * This example shows how to use SSL_Client to connect to SSE (Server-Sent Events) server. + * + * Locate the sse.php on your PHP web server to test. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +ESP_SSLClient ssl_client; + +WiFiClient basic_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + + +String host = "your_server_ip_or_host"; +String uri = "/sse.php"; // if sse.php is located in the root directory. +uint16_t port = 443; + +bool connect() +{ + Serial.println(); + Serial.print("Connecting to server..."); + + if (ssl_client.connect(host.c_str(), port)) + { + Serial.println(" ok"); + + String header = "GET "; + header += uri; + header += " HTTP/1.1\r\n"; + header += "Host: "; + header += host; + header += "\r\n\r\n"; + + int ret = ssl_client.print(header); + return ret == header.length(); + } + else + { + ssl_client.stop(); + Serial.println(" failed\n"); + delay(2000); + } + + return false; +} + +void setup() +{ + Serial.begin(115200); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); + + connect(); +} + +void loop() +{ + if (!ssl_client.connected() && !connect()) + return; + + while (ssl_client.connected() && ssl_client.available()) + { + Serial.print(ssl_client.readStringUntil('\r')); + } +} \ No newline at end of file diff --git a/examples/SSE/sse.php b/examples/SSE/sse.php new file mode 100644 index 0000000..029bddf --- /dev/null +++ b/examples/SSE/sse.php @@ -0,0 +1,26 @@ + 0) { + ob_flush(); + } + + flush(); + + if (connection_aborted()) { + return; + } + + sleep(2); // Event interval in seconds. +} + +?> \ No newline at end of file diff --git a/examples/Session/Session.ino b/examples/Session/Session.ino new file mode 100644 index 0000000..139276e --- /dev/null +++ b/examples/Session/Session.ino @@ -0,0 +1,223 @@ +/** + * This example shows how to connect to server via https using the SSL client and store the session to speed up handshake. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP_SSLSClient + * + * Copyright (c) 2023 mobizt + * + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || defined(ARDUINO_GIGA) +#include +#elif defined(ESP8266) +#include +#elif __has_include() || defined(ARDUINO_NANO_RP2040_CONNECT) +#include +#elif __has_include() +#include +#elif __has_include() || defined(ARDUINO_UNOWIFIR4) +#include +#elif __has_include() || defined(ARDUINO_PORTENTA_C33) +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "WIFI_AP" +#define WIFI_PASSWORD "WIFI_PASSWORD" + +ESP_SSLClient ssl_client; + +// EthernetClient basic_client; +// GSMClient basic_client; +WiFiClient basic_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +BearSSL_Session session1; + +BearSSL_Session session2; + +const char *host1 = "reqres.in"; + +const char *uri1 = "/api/users"; + +const char *contentType1 = "application/json"; + +String payload1 = "{\"title\":\"hello\"}"; + +const char *host2 = "jsonplaceholder.typicode.com"; + +const char *uri2 = "/posts"; + +const char *contentType2 = "application/json"; + +String payload2 = "{\"title\":\"foo\",\"body\": \"bar\",\"userId\": 1}"; + +void connect(const char *method, BearSSL_Session *session, uint32_t timeout, bool closeSession, const char *host, uint16_t port, const char *uri, const char *contentType, const char *payload, bool showResponse) +{ + + if (session) + { + if (session->getSession()->cipher_suite > 0) + Serial.println("### CONNECT WITH SESSION"); + else + Serial.println("### CONNECT WITH EMPTY SESSION"); + } + else + Serial.println("### CONNECT WITHOUT SESSION"); + + unsigned long ms = millis(); + + // Validation for currently connecting host and port. + // Close connection when it's not match that of the last connection. + ssl_client.validate(host, port); + + if (!ssl_client.connected()) + { + Serial.print("Connecting to "); + Serial.print(host); + Serial.print("... "); + + ssl_client.setSession(session); + + if (!ssl_client.connect(host, port)) + { + Serial.println(" failed\n"); + Serial.println(); + return; + } + Serial.println(" ok"); + Serial.print("Connect and negotiate time... "); + Serial.println(millis() - ms); + } + + Serial.print("Send "); + Serial.print(method); + Serial.println(" request..."); + + ssl_client.print(method); + ssl_client.print(" "); + if (uri[0] != '/') + ssl_client.print("/"); + ssl_client.print(uri); + ssl_client.print(" HTTP/1.1\r\n"); + ssl_client.print("Host: "); + ssl_client.print(host); + ssl_client.print("\r\n"); + + if (strcasecmp(method, "post") == 0 || strcasecmp(method, "put") == 0) + { + ssl_client.print("Content-Type: "); + ssl_client.print(contentType); + ssl_client.print("\r\n"); + ssl_client.print("Content-Length: "); + ssl_client.print(strlen(payload)); + ssl_client.print("\r\n\r\n"); + ssl_client.print(payload); + } + + Serial.print("Read response..."); + ms = millis(); + while (!ssl_client.available() && millis() - ms < timeout) + { + delay(0); + } + + if (millis() - ms > timeout) + { + Serial.println(" timed out"); + } + else + { + if (showResponse) + Serial.println(); + + while (ssl_client.available()) + { + char res = ssl_client.read(); + if (showResponse) + Serial.print(res); + } + + if (!showResponse) + Serial.println("ok"); + + Serial.println(); + } + + if (closeSession) + ssl_client.stop(); + + Serial.println(); +} + +void setup() +{ + Serial.begin(115200); + + ssl_client.setSession(&session1); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + // ignore server ssl certificate verification + ssl_client.setInsecure(); + + // Set the receive and transmit buffers size in bytes for memory allocation (512 to 16384). + ssl_client.setBufferSizes(1024 /* rx */, 512 /* tx */); + + /** Call setDebugLevel(level) to set the debug + * esp_ssl_debug_none = 0 + * esp_ssl_debug_error = 1 + * esp_ssl_debug_warn = 2 + * esp_ssl_debug_info = 3 + * esp_ssl_debug_dump = 4 + */ + ssl_client.setDebugLevel(1); + + // Assign the basic client + // Due to the basic_client pointer is assigned, to avoid dangling pointer, basic_client should be existed + // as long as it was used by ssl_client for transportation. + ssl_client.setClient(&basic_client); +} + +void loop() +{ + connect("POST", nullptr, 3000, true, host1, 443, uri1, contentType1, payload1.c_str(), false); + delay(5000); + connect("POST", nullptr, 3000, true, host2, 443, uri2, contentType2, payload2.c_str(), false); + delay(5000); + + connect("POST", &session1, 3000, true, host1, 443, uri1, contentType1, payload1.c_str(), false); + delay(5000); + connect("POST", &session2, 3000, true, host2, 443, uri2, contentType2, payload2.c_str(), false); + delay(5000); +} \ No newline at end of file