123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838 |
- #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h"
- #define REPEAT_CONNECTION 1
- #define WOLFSSL_PORT 11111
- #define SERIAL_BAUD 115200
- #define SHUTDOWN_DELAY_MS 2000
- #define RECONNECT_ATTEMPTS 20
- #define WOLFSSL_SERVER_EXAMPLE
- #if defined(MY_PRIVATE_CONFIG)
-
- #include MY_PRIVATE_CONFIG
- static const char* ssid PROGMEM = MY_ARDUINO_WIFI_SSID;
- static const char* password PROGMEM = MY_ARDUINO_WIFI_PASSWORD;
- #else
-
- static const char* ssid PROGMEM = "your_SSID";
- static const char* password PROGMEM = "your_PASSWORD";
- #endif
- #define BROADCAST_ADDRESS "255.255.255.255"
- #ifdef USE_NTP_LIB
- #include <NTPClient.h>
- #endif
- #include <wolfssl.h>
- #include <wolfssl/wolfcrypt/settings.h>
- #include <wolfssl/ssl.h>
- #include <wolfssl/certs_test.h>
- #include <wolfssl/wolfcrypt/error-crypt.h>
- #if defined(DEBUG_WOLFSSL)
- #define PROGRESS_DOT F("")
- #else
- #define PROGRESS_DOT F(".")
- #endif
- #define xstr(x) str(x)
- #define str(x) #x
- #if defined(ESP32)
- #define USING_WIFI
- #include <WiFi.h>
- #include <WiFiUdp.h>
- #ifdef USE_NTP_LIB
- WiFiUDP ntpUDP;
- #endif
-
- #ifndef F
- #define F
- #endif
- WiFiClient client;
- WiFiServer server(WOLFSSL_PORT);
- #elif defined(ESP8266)
- #define USING_WIFI
- #include <ESP8266WiFi.h>
- WiFiClient client;
- WiFiServer server(WOLFSSL_PORT);
- #elif defined(ARDUINO_SAM_DUE)
- #include <SPI.h>
-
- #include <Ethernet.h>
- EthernetClient client;
- EthernetClient server(WOLFSSL_PORT);
- #elif defined(ARDUINO_SAMD_NANO_33_IOT)
- #define USING_WIFI
- #include <SPI.h>
- #include <WiFiNINA.h> /* Needs Arduino WiFiNINA library installed manually */
- WiFiClient client;
- WiFiServer server(WOLFSSL_PORT);
- #elif defined(ARDUINO_ARCH_RP2040)
- #define USING_WIFI
- #include <SPI.h>
- #include <WiFiNINA.h>
- WiFiClient client;
- WiFiServer server(WOLFSSL_PORT);
- #elif defined(USING_WIFI)
- #define USING_WIFI
- #include <WiFi.h>
- #include <WiFiUdp.h>
- #ifdef USE_NTP_LIB
- WiFiUDP ntpUDP;
- #endif
- WiFiClient client;
- WiFiServer server(WOLFSSL_PORT);
- #else
- #define USING_WIFI
- WiFiClient client;
- WiFiServer server(WOLFSSL_PORT);
- #endif
- #if defined(HAVE_SNI) \
- || defined(HAVE_MAX_FRAGMENT) \
- || defined(HAVE_TRUSTED_CA) \
- || defined(HAVE_TRUNCATED_HMAC) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
- || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
- || defined(HAVE_SUPPORTED_CURVES) \
- || defined(HAVE_ALPN) \
- || defined(HAVE_SESSION_TICKET) \
- || defined(HAVE_SECURE_RENEGOTIATION) \
- || defined(HAVE_SERVER_RENEGOTIATION_INFO)
- #endif
- static WOLFSSL_CTX* ctx = NULL;
- static WOLFSSL* ssl = NULL;
- static char* wc_error_message = (char*)malloc(80 + 1);
- static char errBuf[80];
- #if defined(MEMORY_STRESS_TEST)
- #define MEMORY_STRESS_ITERATIONS 100
- #define MEMORY_STRESS_BLOCK_SIZE 1024
- #define MEMORY_STRESS_INITIAL (4*1024)
- static char* memory_stress[MEMORY_STRESS_ITERATIONS];
- static int mem_ctr = 0;
- #endif
- static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
- static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
- static int reconnect = RECONNECT_ATTEMPTS;
- static int lng_index PROGMEM = 0;
- #if defined(__arm__)
- #include <malloc.h>
- extern char _end;
- extern "C" char *sbrk(int i);
- static char *ramstart=(char *)0x20070000;
- static char *ramend=(char *)0x20088000;
- #endif
- int fail_wait(void) {
- show_memory();
- Serial.println(F("Failed. Halt."));
- while (1) {
- delay(1000);
- }
- return 0;
- }
- int show_memory(void)
- {
- #if defined(__arm__)
- struct mallinfo mi = mallinfo();
- char *heapend=sbrk(0);
- register char * stack_ptr asm("sp");
- #if defined(DEBUG_WOLFSSL_VERBOSE)
- Serial.print(" arena=");
- Serial.println(mi.arena);
- Serial.print(" ordblks=");
- Serial.println(mi.ordblks);
- Serial.print(" uordblks=");
- Serial.println(mi.uordblks);
- Serial.print(" fordblks=");
- Serial.println(mi.fordblks);
- Serial.print(" keepcost=");
- Serial.println(mi.keepcost);
- #endif
- #if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST)
- Serial.print("Estimated free memory: ");
- Serial.print(stack_ptr - heapend + mi.fordblks);
- Serial.println(F(" bytes"));
- #endif
- #if (0)
-
- Serial.print("RAM Start %lx\n", (unsigned long)ramstart);
- Serial.print("Data/Bss end %lx\n", (unsigned long)&_end);
- Serial.print("Heap End %lx\n", (unsigned long)heapend);
- Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr);
- Serial.print("RAM End %lx\n", (unsigned long)ramend);
- Serial.print("Heap RAM Used: ",mi.uordblks);
- Serial.print("Program RAM Used ",&_end - ramstart);
- Serial.print("Stack RAM Used ",ramend - stack_ptr);
- Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks);
- #endif
- #else
- Serial.println(F("show_memory() not implemented for this platform"));
- #endif
- return 0;
- }
- int EthernetSend(WOLFSSL* ssl, char* message, int sz, void* ctx) {
- int sent = 0;
- (void)ssl;
- (void)ctx;
- sent = client.write((byte*)message, sz);
- return sent;
- }
- int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx) {
- int ret = 0;
- (void)ssl;
- (void)ctx;
- while (client.available() > 0 && ret < sz) {
- reply[ret++] = client.read();
- }
- return ret;
- }
- int setup_hardware(void) {
- int ret = 0;
- #if defined(ARDUINO_SAMD_NANO_33_IOT)
- Serial.println(F("Detected known tested and working Arduino Nano 33 IoT"));
- #elif defined(ARDUINO_ARCH_RP2040)
- Serial.println(F("Detected known tested and working Arduino RP-2040"));
- #elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG)
-
- pmc_enable_periph_clk(ID_TRNG);
- trng_enable(TRNG);
- Serial.println(F("Enabled ARM TRNG"));
- #endif
- show_memory();
- randomSeed(analogRead(0));
- return ret;
- }
- int setup_datetime(void) {
- int ret = 0;
- int ntp_tries = 20;
-
- #ifdef USE_NTP_LIB
- #if defined(ESP32)
- NTPClient timeClient(ntpUDP, "pool.ntp.org");
- timeClient.begin();
- timeClient.update();
- delay(1000);
- while (!timeClient.isTimeSet() && (ntp_tries > 0)) {
- timeClient.forceUpdate();
- Serial.println(F("Waiting for NTP update"));
- delay(2000);
- ntp_tries--;
- }
- if (ntp_tries <= 0) {
- Serial.println(F("Warning: gave up waiting on NTP"));
- }
- Serial.println(timeClient.getFormattedTime());
- Serial.println(timeClient.getEpochTime());
- #endif
- #endif
- #if defined(ESP32)
-
- ntp_tries = 5;
-
- configTime(0, 0, "pool.ntp.org");
-
- while ((time(nullptr) <= 100000) && ntp_tries > 0) {
- Serial.println(F("Waiting for time to be set..."));
- delay(2000);
- ntp_tries--;
- }
- #endif
- return ret;
- }
- int setup_network(void) {
- int ret = 0;
- #if defined(USING_WIFI)
- int status = WL_IDLE_STATUS;
-
- #if defined(ESP8266) || defined(ESP32)
- WiFi.mode(WIFI_STA);
- #else
- String fv;
- if (WiFi.status() == WL_NO_MODULE) {
- Serial.println("Communication with WiFi module failed!");
-
- while (true) ;
- }
- fv = WiFi.firmwareVersion();
- if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
- Serial.println("Please upgrade the firmware");
- }
- #endif
- Serial.print(F("Connecting to WiFi "));
- Serial.print(ssid);
- status = WiFi.begin(ssid, password);
- while (status != WL_CONNECTED) {
- delay(1000);
- Serial.print(F("."));
- Serial.print(status);
- status = WiFi.status();
- }
- Serial.println(F(" Connected!"));
- #else
-
- byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
- IPAddress ip(192, 168, 1, 42);
- IPAddress myDns(192, 168, 1, 1);
- Ethernet.init(10);
-
-
-
-
-
- Serial.println(F("Initialize Ethernet with DHCP:"));
- if (Ethernet.begin(mac) == 0) {
- Serial.println(F("Failed to configure Ethernet using DHCP"));
-
- if (Ethernet.hardwareStatus() == EthernetNoHardware) {
- Serial.println(F("Ethernet shield was not found."));
- while (true) {
- delay(1);
- }
- }
- if (Ethernet.linkStatus() == LinkOFF) {
- Serial.println(F("Ethernet cable is not connected."));
- }
-
- Ethernet.begin(mac, ip, myDns);
- }
- else {
- Serial.print(F(" DHCP assigned IP "));
- Serial.println(Ethernet.localIP());
- }
-
- #endif
- Serial.println(F("********************************************************"));
- Serial.print(F(" wolfSSL Example Server IP = "));
- #if defined(USING_WIFI)
- Serial.println(WiFi.localIP());
- #else
- Serial.println(Ethernet.localIP());
- #endif
-
-
- Serial.println(F("********************************************************"));
- Serial.println(F("Setup network complete."));
- return ret;
- }
- int setup_wolfssl(void) {
- int ret = 0;
- WOLFSSL_METHOD* method;
-
- #if defined(WOLFSSL_USER_SETTINGS_ID)
- Serial.print(F("WOLFSSL_USER_SETTINGS_ID: "));
- Serial.println(F(WOLFSSL_USER_SETTINGS_ID));
- #else
- Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found."));
- #endif
- #if defined(NO_WOLFSSL_SERVER)
- Serial.println(F("wolfSSL server code disabled to save space."));
- #endif
- #if defined(NO_WOLFSSL_CLIENT)
- Serial.println(F("wolfSSL client code disabled to save space."));
- #endif
- #if defined(DEBUG_WOLFSSL)
- wolfSSL_Debugging_ON();
- Serial.println(F("wolfSSL Debugging is On!"));
- #else
- Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
- #endif
-
- #if defined(NO_SESSION_CACHE)
- Serial.println(F("wolfSSL TLS NO_SESSION_CACHE"));
- #elif defined(MICRO_SESSION_CACHEx)
- Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE"));
- #elif defined(SMALL_SESSION_CACHE)
- Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE"));
- #elif defined(MEDIUM_SESSION_CACHE)
- Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE"));
- #elif defined(BIG_SESSION_CACHE)
- Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE"));
- #elif defined(HUGE_SESSION_CACHE)
- Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
- #elif defined(HUGE_SESSION_CACHE)
- Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
- #else
- Serial.println(F("WARNING: Unknown or no TLS session cache setting."));
-
- #endif
- ret = wolfSSL_Init();
- if (ret == WOLFSSL_SUCCESS) {
- Serial.println("Successfully called wolfSSL_Init");
- }
- else {
- Serial.println("ERROR: wolfSSL_Init failed");
- }
-
- Serial.println("Here we go!");
- method = wolfSSLv23_server_method();
- if (method == NULL) {
- Serial.println(F("unable to get wolfssl server method"));
- fail_wait();
- }
- ctx = wolfSSL_CTX_new(method);
- if (ctx == NULL) {
- Serial.println(F("unable to get ctx"));
- fail_wait();
- }
- return ret;
- }
- int setup_certificates(void) {
- int ret = 0;
- Serial.println(F("Initializing certificates..."));
- show_memory();
-
- wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
-
- Serial.println("Initializing certificates...");
- ret = wolfSSL_CTX_use_certificate_buffer(ctx,
- CTX_SERVER_CERT,
- CTX_SERVER_CERT_SIZE,
- CTX_CA_CERT_TYPE);
- if (ret == WOLFSSL_SUCCESS) {
- Serial.print("Success: use certificate: ");
- Serial.println(xstr(CTX_SERVER_CERT));
- }
- else {
- Serial.print("Error: wolfSSL_CTX_use_certificate_buffer failed: ");
- wc_ErrorString(ret, wc_error_message);
- Serial.println(wc_error_message);
- fail_wait();
- }
-
- ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
- CTX_SERVER_KEY,
- CTX_SERVER_KEY_SIZE,
- CTX_SERVER_KEY_TYPE);
- if (ret == WOLFSSL_SUCCESS) {
- Serial.print("Success: use private key buffer: ");
- Serial.println(xstr(CTX_SERVER_KEY));
- }
- else {
- Serial.print("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: ");
- wc_ErrorString(ret, wc_error_message);
- Serial.println(wc_error_message);
- fail_wait();
- }
- return ret;
- }
- void setup(void) {
- int i = 0;
- Serial.begin(SERIAL_BAUD);
- while (!Serial && (i < 10)) {
-
- delay(1000);
- i++;
- }
- Serial.println(F(""));
- Serial.println(F(""));
- Serial.println(F("wolfSSL TLS Server Example Startup."));
-
- #if defined(DEBUG_WOLFSSL)
- wolfSSL_Debugging_ON();
- #endif
-
- #if defined(MEMORY_STRESS_TEST)
- Serial.println(F("WARNING: Memory Stress Test Active!"));
- Serial.print(F("Allocating extra memory: "));
- Serial.print(MEMORY_STRESS_INITIAL);
- Serial.println(F(" bytes..."));
- memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL);
- show_memory();
- #endif
- setup_hardware();
- setup_network();
- setup_datetime();
- setup_wolfssl();
- setup_certificates();
-
- wolfSSL_SetIOSend(ctx, EthernetSend);
- wolfSSL_SetIORecv(ctx, EthernetReceive);
- #if defined THIS_USER_SETTINGS_VERSION
- Serial.print(F("This user_settings.h version:"))
- Serial.println(THIS_USER_SETTINGS_VERSION)
- #endif
-
- Serial.println(F("Completed Arduino setup()"));
- server.begin();
- Serial.println("Begin Server... (waiting for remote client to connect)");
-
- return;
- }
- int error_check(int this_ret, bool halt_on_error,
- const __FlashStringHelper* message) {
- int ret = 0;
- if (this_ret == WOLFSSL_SUCCESS) {
- Serial.print(F("Success: "));
- Serial.println(message);
- }
- else {
- Serial.print(F("ERROR: return = "));
- Serial.print(this_ret);
- Serial.print(F(": "));
- Serial.println(message);
- Serial.println(wc_GetErrorString(this_ret));
- if (halt_on_error) {
- fail_wait();
- }
- }
- show_memory();
- return ret;
- }
- int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
- const __FlashStringHelper* message) {
- int err = 0;
- if (ssl == NULL) {
- Serial.println(F("ssl is Null; Unable to allocate SSL object?"));
- #ifndef DEBUG_WOLFSSL
- Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more."));
- #else
- Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes."));
- #endif
- Serial.print(F("ERROR: "));
- Serial.println(message);
- show_memory();
- if (halt_on_error) {
- fail_wait();
- }
- }
- else {
- err = wolfSSL_get_error(ssl, this_ret);
- if (err == WOLFSSL_SUCCESS) {
- Serial.print(F("Success m: "));
- Serial.println(message);
- }
- else {
- if (err < 0) {
- wolfSSL_ERR_error_string(err, errBuf);
- Serial.print(F("WOLFSSL Error: "));
- Serial.print(err);
- Serial.print(F("; "));
- Serial.println(errBuf);
- }
- else {
- Serial.println(F("Success: ssl object."));
- }
- }
- }
- return err;
- }
- void loop() {
- char errBuf[80] = "(no error";
- char reply[80] = "(no reply)";
- const char msg[] = "I hear you fa shizzle!";
- const char* cipherName;
- int input = 0;
- int replySz = 0;
- int retry_shutdown = SHUTDOWN_DELAY_MS;
- int ret = 0;
- IPAddress broadcast_address(255, 255, 255, 255);
-
- client = server.available();
- if (client) {
- Serial.println("Have Client");
- while (!client.connected()) {
-
- delay(10);
- }
- Serial.print("Client connected from remote IP: ");
- Serial.println(client.remoteIP());
- ssl = wolfSSL_new(ctx);
- if (ssl == NULL) {
- Serial.println("Unable to allocate SSL object");
- fail_wait();
- }
- ret = wolfSSL_accept(ssl);
- if (ret != WOLFSSL_SUCCESS) {
- ret = wolfSSL_get_error(ssl, 0);
- wolfSSL_ERR_error_string(ret, errBuf);
- Serial.print("TLS Accept Error: ");
- Serial.println(errBuf);
- }
- cipherName = wolfSSL_get_cipher(ssl);
- Serial.print("SSL cipher suite is ");
- Serial.println(cipherName);
- Serial.print("Server Read: ");
- while (!client.available()) {
-
- }
-
- while (wolfSSL_pending(ssl)) {
- input = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
- if (input < 0) {
- ret = wolfSSL_get_error(ssl, 0);
- wolfSSL_ERR_error_string(ret, errBuf);
- Serial.print("TLS Read Error: ");
- Serial.println(errBuf);
- break;
- }
- else if (input > 0) {
- replySz = input;
- reply[input] = '\0';
- Serial.print(reply);
- }
- else {
- Serial.println("<end of reply, input == 0>");
- }
- }
-
- memset(reply, 0, sizeof(reply));
- memcpy(reply, msg, sizeof(msg));
- replySz = strnlen(reply, sizeof(reply));
- Serial.println("Sending reply...");
- if ((wolfSSL_write(ssl, reply, replySz)) != replySz) {
- ret = wolfSSL_get_error(ssl, 0);
- wolfSSL_ERR_error_string(ret, errBuf);
- Serial.print("TLS Write Error: ");
- Serial.println(errBuf);
- }
- else {
- Serial.println("Reply sent!");
- }
- Serial.println("Shutdown!");
- do {
- delay(1);
- retry_shutdown--;
- ret = wolfSSL_shutdown(ssl);
- } while ((ret == WOLFSSL_SHUTDOWN_NOT_DONE) && (retry_shutdown > 0));
- if (retry_shutdown <= 0) {
-
- Serial.println("Warning! Shutdown did not properly complete.");
- }
- wolfSSL_free(ssl);
- Serial.println("Connection complete.");
- if (REPEAT_CONNECTION) {
- Serial.println();
- Serial.println("Waiting for next connection.");
- }
- else {
- client.stop();
- Serial.println("Done!");
- while (1) {
-
- delay(100);
- }
- }
- }
- else {
-
- }
- delay(100);
- }
|