---
title: "ESP32: ethernet w5500 with plain (HTTP) and SSL (HTTPS)"
url: "https://maker.wiznet.io/bruno/projects/esp32%3A-ethernet-w5500-with-plain-http-and-ssl-https/"
markdown_url: "https://maker.wiznet.io/bruno/projects/esp32%3A-ethernet-w5500-with-plain-http-and-ssl-https/md"
type: "UCC: User Created Content"
author: "RENZO MISCHIANTI"
author_url: "https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "RENZO MISCHIANTI"
original_url: "https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/"
published: "2022-10-19"
language: "en"
likes: 7
views: 1689
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# ESP32: ethernet w5500 with plain (HTTP) and SSL (HTTPS)

> ESP32: ethernet w5500 with plain (HTTP) and SSL (HTTPS)

Original author: RENZO MISCHIANTI (source: https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/)

## Article

## ESP32: ethernet w5500 with plain (HTTP) and SSL (HTTPS)

BY [RENZO MISCHIANTI](https://www.mischianti.org/author/reef/) · 18 OCTOBER 2022

**Spread the love**

First of all, it must be said that the ESP32 already has a MAC, a TCP / IP stack, and an Arduino network library, but we will still use it with an Ethernet library with W5500 devices since they are the most popular of all and work very well.

[![ESP32 use ethernet w5500 with plain HTTP and SSL HTTPS](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-use-ethernet-w5500-with-plain-HTTP-and-SSL-HTTPS-1024x552.jpg)](https://www.mischianti.org/esp32-use-ethernet-w5500-with-plain-http-and-ssl-https/)

**ESP32 use ethernet w5500 with plain HTTP and SSL HTTPS**

Many people ask me for some examples of wired connections; in my mind, the first thing I thought of is the w5500 device, one of the most famous and powerful. We’ll start to learn how to manage plain and SSL requests.

- [Devices](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Devices)
  - [Features](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Features)

- [Wiring](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Wiring)

- [Library](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Library)
  - [SSLClient](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#SSLClient)
  - [SSLClient with Ethernet](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#SSLClient_with_Ethernet)
    - [Buffer extension](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Buffer_extension)
    - [Manual Modification](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Manual_Modification)

- [Code](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Code)
  - [Initialize device](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Initialize_device)
  - [Simple HTTP request](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Simple_HTTP_request)
  - [HTTPS request](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#HTTPS_request)
    - [Retrieve certificate](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Retrieve_certificate)
    - [Add SSLClient wrapper](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Add_SSLClient_wrapper)

- [Thanks](https://www.mischianti.org/2022/10/18/esp32-ethernet-w5500-with-plain-http-and-ssl-https/#Thanks)

## Devices

The W5500 chip is a Hardwired TCP/IP embedded Ethernet controller that provides an easier Internet connection to embedded systems. W5500 enables users to have Internet connectivity in their applications just by using the single chip in which TCP/IP stack, 10/100 Ethernet MAC, and PHY are embedded.

WIZnet‘s Hardwired TCP/IP is the market-proven technology supporting TCP, UDP, IPv4, ICMP, ARP, IGMP, and PPPoE protocols. W5500 embeds the 32Kbyte internal memory buffer for the Ethernet packet processing. If you use W5500, you can implement the Ethernet application by adding the simple socket program. It’s a faster and easier way rather than using any other Embedded Ethernet solution. Users can use eight independent hardware sockets simultaneously.

SPI (Serial Peripheral Interface) is provided for easy integration with the external MCU. The W5500’s SPI supports 80 MHz speed. To reduce the system’s power consumption, W5500 provides WOL (Wake on LAN) and power-down mode.

### Features

- Supports Hardwired TCP/IP Protocols : TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE

- Supports 8 independent sockets simultaneously

- Supports Power down mode

- Supports Wake on LAN over UDP

- Supports High Speed Serial Peripheral Interface(SPI MODE 0, 3)

- Internal 32Kbytes Memory for TX/RX Buffers

- 10BaseT/100BaseTX Ethernet PHY embedded

- Supports Auto Negotiation (Full and half duplex, 10 and 100-based )

- Not supports IP Fragmentation

- 3.3V operation with 5V I/O signal tolerance

- LED outputs (Full/Half duplex, Link, Speed, Active)

- 48 Pin LQFP Lead-Free Package (7x7mm, 0.5mm pitch)

There is a wide series of w5500 devices, but the most popular are 2 in particular.

The less expensive is the w5500 that you can see in the photo.

[![w5500 ethernet network modules spi](https://www.mischianti.org/wp-content/uploads/2022/03/w5500-ethernet-network-modules-spi-1024x683.jpg)](https://www.mischianti.org/w5500-ethernet-network-modules-spi/)

**w5500 ethernet network modules SPI**

But now there is a compact version named w5500 lite, which is very interesting as a device for production.

[![w5500 lite ethernet network modules spi](https://www.mischianti.org/wp-content/uploads/2022/03/w5500-lite-ethernet-network-modules-spi.jpg)](https://www.mischianti.org/w5500-lite-ethernet-network-modules-spi/)

**w5500 lite ethernet network modules SPI**

Here my selection of tested ethernet devices [w5500 lite](https://s.click.aliexpress.com/e/_AEq4RF) - [w5500](https://s.click.aliexpress.com/e/_A9iD4p) - [enc26j60 mini](https://s.click.aliexpress.com/e/_9z4IDn) - [enc26j60](https://s.click.aliexpress.com/e/_Al41t7)

## Wiring

[![ESP32 DOIT DEV KIT v1 pinout](https://www.mischianti.org/wp-content/uploads/2021/03/ESP32-DOIT-DEV-KIT-v1-pinout-mischianti-1024x501.jpg)](https://www.mischianti.org/wp-content/uploads/2021/03/ESP32-DOIT-DEV-KIT-v1-pinout-mischianti.jpg)

**ESP32 DOIT DEV KIT v1 pinout**

Here my selection of esp32 devices [AliExpress ESP32 Dev Kit v1](http://s.click.aliexpress.com/e/_BfhH1zIB) - [AliExpress selectable](http://s.click.aliexpress.com/e/_dYURjFZ) - [AliExpress TTGO T-Display 1.14 ESP32](http://s.click.aliexpress.com/e/_dYXhHDz) - [AliExpress NodeMCU V3 V2 ESP8266 Lolin32](http://s.click.aliexpress.com/e/_dX7xZnt) - [AliExpress WeMos Lolin32 CP2104 CH340](https://s.click.aliexpress.com/e/_dT07BDN) - [AliExpress ESP32-CAM programmer](https://s.click.aliexpress.com/e/_98hjfN) - [AliExpress ESP32-CAM bundle](https://s.click.aliexpress.com/e/_9HHJfC) - [AliExpress ESP32-WROOM-32](https://s.click.aliexpress.com/e/_9j2te7) - [AliExpress ESP32-S](https://s.click.aliexpress.com/e/_AmwyQf)

[![](https://maker.wiznet.io/upload/mirror/body/0b486ea3c55fdcd7fb15.jpg)](https://www.pcbway.com/?from=mischianti702)

This device uses an SPI interface; by default, I will use a base SPI interface.

[![ESP32 DOIT DevKit v1 w5500 wiring breadboard](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-wiring-1024x350.jpg)](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-wiring.jpg)

**ESP32 DOIT DevKit v1 w5500 wiring breadboard**

| **ESP32** | **w5500** |
| --- | --- |
| D5 | CS |
| D18 | SCK |
| D19 | MISO |
| D23 | MOSI |
| 3.3v (better with external 200mha) | VCC |
| GND | GND |

Same connection for w5500 lite, but the previous w5500 device can work with 3.3v of ESP32 (not ever true); this device It’s improbable that works without an external power supply.

[![ESP32 DOIT DevKit v1 w5500 lite wiring breadboard](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-lite-wiring-bb-1024x629.jpg)](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-lite-wiring-bb.jpg)

**ESP32 DOIT DevKit v1 w5500 lite wiring breadboardPay attention not all devices have so much ampere to power the w5500 device, so if you have trouble you must add an external power supply.**

If you have trouble try to power the Ethernet device with an external power supply.

[![ESP32 DOIT DevKit v1 w5500 wiring external power supply](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-wiring-external-power-supply-1024x444.jpg)](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-wiring-external-power-supply.jpg)

**ESP32 DOIT DevKit v1 w5500 wiring external power supply**

## Library

A wide selection of libraries exists, but the [standard one Is the best choice](https://github.com/arduino-libraries/Ethernet). You can find It in the standard Arduino library manager.

[![Arduino esp32 ethernet w5500 library manager](https://www.mischianti.org/wp-content/uploads/2022/03/Arduino-esp32-ethernet-library-w5500-manager.jpg)](https://www.mischianti.org/wp-content/uploads/2022/03/Arduino-esp32-ethernet-library-w5500-manager.jpg)

**Arduino esp32 ethernet w5500 library manager**

### SSLClient

This library and device do not support SSL, so adding these features exists an alternate library named SSLClient that needs a little patch of Ethernet.

SSLClient adds [TLS 1.2](https://www.websecurity.symantec.com/security-topics/what-is-ssl-tls-https) functionality to any network library implementing the [Arduino Client interface](https://www.arduino.cc/en/Reference/ClientConstructor), including the Arduino [EthernetClient](https://www.arduino.cc/en/Reference/EthernetClient) and [WiFiClient](https://www.arduino.cc/en/Reference/WiFiClient) classes. SSLClient was created to integrate TLS seamlessly with the Arduino infrastructure using [BearSSL](https://bearssl.org/) as an underlying TLS engine. Unlike [ArduinoBearSSL](https://github.com/arduino-libraries/ArduinoBearSSL), SSLClient is entirely self-contained and does not require any additional hardware (other than a network connection). **(cit.)**

[![Arduino esp32 ethernet w5500 SSLClient library manager](https://www.mischianti.org/wp-content/uploads/2022/03/Arduino-esp32-ethernet-w5500-SSLClient-library-manager.jpg)](https://www.mischianti.org/wp-content/uploads/2022/03/Arduino-esp32-ethernet-w5500-SSLClient-library-manager.jpg)

**Arduino esp32 ethernet w5500 SSLClient library manager**

### SSLClient with Ethernet

If you are using the [Arduino Ethernet library](https://github.com/arduino-libraries/Ethernet), you will need to modify the library to support the large buffer sizes required by SSL (detailed in resources). You can either modify the library yourself or use this fork of the Ethernet library with the modification. To use the fork: download a zipped copy of the [fork through GitHub](https://github.com/OPEnSLab-OSU/EthernetLarge), use the “add a .zip library” button in Arduino to install the library, and replace `#include "Ethernet.h"` it with `#include "EthernetLarge.h"` in your sketch. Alternatively, if, for some reason, this solution does not work, you can apply the modification manually using the instructions below.

#### Buffer extension

I also notice that to get good stability, you probably must change something else.

In SSLClient.h you must change this line.

| `unsigned` `char` `m_iobuf[``2048``];` |
| --- |

to

| `unsigned` `char` `m_iobuf[BR_SSL_BUFSIZE_BIDI];` |
| --- |

#### Manual Modification

First, find the location of the library in the directory where Arduino is installed (`C:\Program Files (x86)\Arduino` on Windows). Inside of this directory, navigate to `libraries\Ethernet\src` (`C:\Program Files (x86)\Arduino\libraries\Ethernet\src` on Windows). Modify `Ethernet.h` to replace these lines:

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | `...` `// Configure the maximum number of sockets to support. W5100 chips can have` `// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes` `// of RAM are used for each socket. Reducing the maximum can save RAM, but` `// you are limited to fewer simultaneous connections.` `#if` `defined(RAMEND) ``&&` `defined(RAMSTART) ``&&` `((RAMEND ``-` `RAMSTART) <``=` `2048``)` `#define` `MAX_SOCK_NUM ``4` `#else` `#define` `MAX_SOCK_NUM ``8` `#endif` `// By default, each socket uses 2K buffers inside the Wiznet chip. If` `// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting` `// this will use larger buffers within the Wiznet chip. Large buffers` `// can really help with UDP protocols like Artnet. In theory larger` `// buffers should allow faster TCP over high-latency links, but this` `// does not always seem to work in practice (maybe Wiznet bugs?)` `//#define ETHERNET_LARGE_BUFFERS` `...` |
| --- | --- |

With this:

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | `...` `// Configure the maximum number of sockets to support. W5100 chips can have` `// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes` `// of RAM are used for each socket. Reducing the maximum can save RAM, but` `// you are limited to fewer simultaneous connections.` `#define` `MAX_SOCK_NUM ``2` `// By default, each socket uses 2K buffers inside the Wiznet chip. If` `// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting` `// this will use larger buffers within the Wiznet chip. Large buffers` `// can really help with UDP protocols like Artnet. In theory larger` `// buffers should allow faster TCP over high-latency links, but this` `// does not always seem to work in practice (maybe Wiznet bugs?)` `#define` `ETHERNET_LARGE_BUFFERS` `...` |
| --- | --- |

You may need to use `sudo` or administrator permissions to make this modification. We change `MAX_SOCK_NUM` and `ETHERNET_LARGE_BUFFERS` so the Ethernet hardware can allocate a larger space for SSLClient. However, a downside of this modification is that we can only have two sockets concurrently. As most microprocessors barely have enough memory for one SSL connection, this limitation will rarely be encountered in practice.

## Code

Now we try to do a simple WebRequest with a native client.

But first, we write the code needed for the connection, we try to ask the IP to the DHCP server, and if It fails, we start a connection with a static IP.

### Initialize device

Ethernet uses the default SPI interface by default, so first, we must set the correct SS pin (probably not needed).

| `// You can use Ethernet.init(pin) to configure the CS pin` `//Ethernet.init(10); // Most Arduino shields` `Ethernet.init(``5``); ``// MKR ETH Shield` `//Ethernet.init(0); // Teensy 2.0` `//Ethernet.init(20); // Teensy++ 2.0` `//Ethernet.init(15); // ESP8266 with Adafruit FeatherWing Ethernet` `//Ethernet.init(33); // ESP32 with Adafruit FeatherWing Ethernet` |
| --- |

This board’s different from LAN8720 (default device for esp32) and needs a MAC address.

| 1 2 3 | `// Enter a MAC address for your controller below.` `// Newer Ethernet shields have a MAC address printed on a sticker on the shield` `byte` `mac[] ``=` `{ ``0xDE``, ``0xAD``, ``0xBE``, ``0xEF``, ``0xFE``, ``0xED` `};` |
| --- | --- |

Then we try to make a DHCP request.

| 1 2 3 | `if` `(Ethernet.begin(mac)) { ``// Dynamic IP setup` `Serial.println``(``"DHCP OK!"``);` `}` |
| --- | --- |

But If it fails, we try to make a static IP connection with these parameters

[![](https://maker.wiznet.io/upload/mirror/body/0b486ea3c55fdcd7fb15.jpg)](https://www.pcbway.com/?from=mischianti702)

| 1 2 3 4 5 | `// Set the static IP address to use if the DHCP fails to assign` `#define` `MYIPADDR ``192``,``168``,``1``,``28` `#define` `MYIPMASK ``255``,``255``,``255``,``0` `#define` `MYDNS ``192``,``168``,``1``,``1` `#define` `MYGW ``192``,``168``,``1``,``1` |
| --- | --- |

and here is the connection code

| `Serial.println``(``"Failed to configure Ethernet using DHCP"``);` `// Check for Ethernet hardware present` `if` `(Ethernet.hardwareStatus() ``==` `EthernetNoHardware) {` `Serial.println``(` `"Ethernet shield was not found. Sorry, can't run without hardware. :("``);` `while` `(``true``) {` `delay``(``1``); ``// do nothing, no point running without Ethernet hardware` `}` `}` `if` `(Ethernet.linkStatus() ``==` `LinkOFF) {` `Serial.println``(``"Ethernet cable is not connected."``);` `}` `IPAddress ip(MYIPADDR);` `IPAddress dns(MYDNS);` `IPAddress gw(MYGW);` `IPAddress sn(MYIPMASK);` `Ethernet.begin(mac, ip, dns, gw, sn);` `Serial.println``(``"STATIC OK!"``);` |
| --- |

### Simple HTTP request

[![ESP32 DOIT DevKit v1 w5500 lite](https://www.mischianti.org/wp-content/uploads/2022/03/ESP32-DOIT-DevKit-v1-w5500-lite-photo-1024x601.jpg)](https://www.mischianti.org/esp32-doit-devkit-v1-w5500-lite-photo/)

**ESP32 DOIT DevKit v1 w5500 lite**

First of all, we’ll try to make a simple HTTP request. I chose an online service created to test this kind of request to do this test.

I’m going to use a simple service given from [httpbin.org](http://httpbin.org/), and you can use the same REST API in [HTTP](http://httpbin.org/#/HTTP_Methods)and [HTTPS](https://httpbin.org/).

Remember that HTTP work on port 80 HTTPS on 443, so to query the endpoint on 443 port, you must validate a certificate.

To make our connection, we use the basic EthernetClient.

| `// Initialize the Ethernet client library` `// with the IP address and port of the server` `// that you want to connect to (port 80 is default for HTTP):` `EthernetClient client;` |
| --- |

And then, we try to connect and make a request to an endpoint in GET.

| `// if you get a connection, report back via serial:` `if` `(client.connect(server, ``80``)) {` `Serial.println``(``"Connected!"``);` `// Make a HTTP request:` `client.println(``"GET /get HTTP/1.1"``);` `client.println(``"Host: httpbin.org"``);` `client.println(``"Connection: close"``);` `client.println();` `} ``else` `{` `// if you didn't get a connection to the server:` `Serial.println``(``"connection failed"``);` `}` |
| --- |

In the loop, wait for a response from the server.

| `// if there are incoming bytes available` `// from the server, read them and print them:` `int` `len ``=` `client.available();` |
| --- |

And then read the response and put it on Serial output.

| `if` `(len > ``0``) {` `byte` `buffer[``80``];` `if` `(len > ``80``) len ``=` `80``;` `client.read(buffer, len);` `if` `(printWebData) {` `Serial.write``(buffer, len); ``// show in the serial monitor (slows some boards)` `}` `byteCount ``=` `byteCount ``+` `len;` `}` `// if the server's disconnected, stop the client:` `if` `(``!``client.connected()) {` `endMicros ``=` `micros``();` `Serial.println``();` `Serial.println``(``"disconnecting."``);` `client.stop();` `Serial.print``(``"Received "``);` `Serial.print``(byteCount);` `Serial.print``(``" bytes in "``);` `float` `seconds ``=` `(``float``)(endMicros ``-` `beginMicros) ``/` `1000000.0``;` `Serial.print``(seconds, ``4``);` `float` `rate ``=` `(``float``)byteCount ``/` `seconds ``/` `1000.0``;` `Serial.print``(``", rate = "``);` `Serial.print``(rate);` `Serial.print``(``" kbytes/second"``);` `Serial.println``();` `// do nothing forevermore:` `while` `(``true``) {` `delay``(``1``);` `}` `}` |
| --- |

And finally, the complete sketch.

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | `/*` `Web client` `This sketch connects to a test website (httpbin.org)` `and try to do a GET request, the output is printed` `on Serial` `by Renzo Mischianti <www.mischianti.org>` [`https://www.mischianti.org`](https://www.mischianti.org/) `*/` `#include` `<SPI.h>` `#include` `<Ethernet.h>` `// if you don't want to use DNS (and reduce your sketch size)` `// use the numeric IP instead of the name for the server:` `//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)` `//char server[] = "www.google.com"; // name address for Google (using DNS)` `char` `server[] ``=` `"httpbin.org"``; ``// name address for Google (using DNS)` `// Enter a MAC address for your controller below.` `// Newer Ethernet shields have a MAC address printed on a sticker on the shield` `byte` `mac[] ``=` `{ ``0xDE``, ``0xAD``, ``0xBE``, ``0xEF``, ``0xFE``, ``0xED` `};` `// Set the static IP address to use if the DHCP fails to assign` `#define` `MYIPADDR ``192``,``168``,``1``,``28` `#define` `MYIPMASK ``255``,``255``,``255``,``0` `#define` `MYDNS ``192``,``168``,``1``,``1` `#define` `MYGW ``192``,``168``,``1``,``1` `// Initialize the Ethernet client library` `// with the IP address and port of the server` `// that you want to connect to (port 80 is default for HTTP):` `EthernetClient client;` `// Variables to measure the speed` `unsigned` `long` `beginMicros, endMicros;` `unsigned` `long` `byteCount ``=` `0``;` `bool printWebData ``=` `true``; ``// set to false for better speed measurement` `void` `setup``() {` `Serial.begin``(``115200``);` `delay``(``1000``);` `Serial.println``(``"Begin Ethernet"``);` `// You can use Ethernet.init(pin) to configure the CS pin` `//Ethernet.init(10); // Most Arduino shields` `Ethernet.init(``5``); ``// MKR ETH Shield` `//Ethernet.init(0); // Teensy 2.0` `//Ethernet.init(20); // Teensy++ 2.0` `//Ethernet.init(15); // ESP8266 with Adafruit FeatherWing Ethernet` `//Ethernet.init(33); // ESP32 with Adafruit FeatherWing Ethernet` `if` `(Ethernet.begin(mac)) { ``// Dynamic IP setup` `Serial.println``(``"DHCP OK!"``);` `}``else``{` `Serial.println``(``"Failed to configure Ethernet using DHCP"``);` `// Check for Ethernet hardware present` `if` `(Ethernet.hardwareStatus() ``==` `EthernetNoHardware) {` `Serial.println``(``"Ethernet shield was not found. Sorry, can't run without hardware. :("``);` `while` `(``true``) {` `delay``(``1``); ``// do nothing, no point running without Ethernet hardware` `}` `}` `if` `(Ethernet.linkStatus() ``==` `LinkOFF) {` `Serial.println``(``"Ethernet cable is not connected."``);` `}` `IPAddress ip(MYIPADDR);` `IPAddress dns(MYDNS);` `IPAddress gw(MYGW);` `IPAddress sn(MYIPMASK);` `Ethernet.begin(mac, ip, dns, gw, sn);` `Serial.println``(``"STATIC OK!"``);` `}` `delay``(``5000``);` `Serial.print``(``"Local IP : "``);` `Serial.println``(Ethernet.localIP());` `Serial.print``(``"Subnet Mask : "``);` `Serial.println``(Ethernet.subnetMask());` `Serial.print``(``"Gateway IP : "``);` `Serial.println``(Ethernet.gatewayIP());` `Serial.print``(``"DNS Server : "``);` `Serial.println``(Ethernet.dnsServerIP());` `Serial.println``(``"Ethernet Successfully Initialized"``);` `// if you get a connection, report back via serial:` `if` `(client.connect(server, ``80``)) {` `Serial.println``(``"Connected!"``);` `// Make a HTTP request:` `client.println(``"GET /get HTTP/1.1"``);` `client.println(``"Host: httpbin.org"``);` `client.println(``"Connection: close"``);` `client.println();` `} ``else` `{` `// if you didn't get a connection to the server:` `Serial.println``(``"connection failed"``);` `}` `beginMicros ``=` `micros``();` `}` `void` `loop``() {` `// if there are incoming bytes available` `// from the server, read them and print them:` `int` `len ``=` `client.available();` `if` `(len > ``0``) {` `byte` `buffer[``80``];` `if` `(len > ``80``) len ``=` `80``;` `client.read(buffer, len);` `if` `(printWebData) {` `Serial.write``(buffer, len); ``// show in the serial monitor (slows some boards)` `}` `byteCount ``=` `byteCount ``+` `len;` `}` `// if the server's disconnected, stop the client:` `if` `(``!``client.connected()) {` `endMicros ``=` `micros``();` `Serial.println``();` `Serial.println``(``"disconnecting."``);` `client.stop();` `Serial.print``(``"Received "``);` `Serial.print``(byteCount);` `Serial.print``(``" bytes in "``);` `float` `seconds ``=` `(``float``)(endMicros ``-` `beginMicros) ``/` `1000000.0``;` `Serial.print``(seconds, ``4``);` `float` `rate ``=` `(``float``)byteCount ``/` `seconds ``/` `1000.0``;` `Serial.print``(``", rate = "``);` `Serial.print``(rate);` `Serial.print``(``" kbytes/second"``);` `Serial.println``();` `// do nothing forevermore:` `while` `(``true``) {` `delay``(``1``);` `}` `}` `}` |
| --- | --- |

The result is this.

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | `Begin Ethernet` `DHCP OK!` `Local IP : 192.168.1.138` `Subnet Mask : 255.255.255.0` `Gateway IP : 192.168.1.1` `DNS Server : 192.168.1.1` `Ethernet Successfully Initialized` `Connected!` `HTTP/1.1 200 OK` `Date: Wed, 09 Mar 2022 11:15:49 GMT` `Content-Type: application/json` `Content-Length: 197` `Connection: close` `Server: gunicorn/19.9.0` `Access-Control-Allow-Origin: *` `Access-Control-Allow-Credentials: true` `{` `"args": {},` `"headers": {` `"Host": "httpbin.org",` `"X-Amzn-Trace-Id": "Root=1-62288c65-1fe4f19070d3ab7c773aee09"` `},` `"origin": "82.51.127.46",` `"url": "`[`http://httpbin.org/get`](http://httpbin.org/get)`"` `}` `disconnecting.` `Received 422 bytes in 0.2663, rate = 1.58 kbytes/second` |
| --- | --- |

### HTTPS request

Now, if we change the endpoint to port 443, we will request a secure server with SSL encryption.

| `if` `(client.connect(server, ``443``)) {` `Serial.println``(``"Connected!"``);` `// Make a HTTP request:` `client.println(``"GET /get HTTP/1.1"``);` `client.println(``"Host: httpbin.org"``);` `client.println(``"Connection: close"``);` `client.println();` `} ``else` `{` `// if you didn't get a connection to the server:` `Serial.println``(``"connection failed"``);` `}` |
| --- |

And we obtain this response.

| `Begin Ethernet` `DHCP OK!` `Local IP : 192.168.1.138` `Subnet Mask : 255.255.255.0` `Gateway IP : 192.168.1.1` `DNS Server : 192.168.1.1` `Ethernet Successfully Initialized` `Connected!` `HTTP/1.1 400 Bad Request` `Server: awselb/2.0` `Date: Wed, 09 Mar 2022 11:23:16 GMT` `Content-Type: text/html` `Content-Length: 220` `Connection: close` `<html>` `<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>` `<body>` `<center><h1>400 Bad Request</h1></center>` `<center>The plain HTTP request was sent to HTTPS port</center>` `</body>` `</html>` `Disconnecting.` `Received 370 bytes in 0.4333, rate = 0.85 kbytes/second` |
| --- |

So the problem is that request and response messages aren’t transmitted using SSL (Secure Sockets Layer) or its successor TLS (Transport Layer Security). To add this feature, we are going to use SSLClient.

#### Retrieve certificate

To use an SSL, we need the server certificate, but in this case, SSLClient uses a trick given by BearSSL implementation. This minimal x509 verification engine allows using of Trust Anchors.

I add a simple online generator that you can find [here](https://www.mischianti.org/online-bearssl-certificate-trust-anchor-retriever-for-minimal-x509-verification-engine/).

You must only write the site’s address (httpbin.org) in the first input box, click `Generate code`, copy the code, and put it inside a file called `trust_anchors.h` and put it inside the sketch folder.

[![BearSSL certificate trust anchor retriever online](https://www.mischianti.org/wp-content/uploads/2022/03/BearSSL-certificate-trust-anchor-retriever-online-589x1024.jpg)](https://www.mischianti.org/wp-content/uploads/2022/03/BearSSL-certificate-trust-anchor-retriever-online.jpg)

Here is the content of `trust_anchors.h`.

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | `#ifndef` `_CERTIFICATES_H_` `#define` `_CERTIFICATES_H_` `#ifdef` `__cplusplus` `extern ``"C"` `{` `#endif` `/* This file is auto-generated by the pycert_bearssl tool. Do not change it manually.` `* Certificates are BearSSL br_x509_trust_anchor format. Included certs:` `*` `* Index: 0` `* Label: Starfield Class 2 Certification Authority` `* Subject: OU=Starfield Class 2 Certification Authority,O=Starfield Technologies\, Inc.,C=US` `* Domain(s): httpbin.org` `*/` `#define` `TAs_NUM ``1` `static` `const` `unsigned` `char` `TA_DN0[] ``=` `{` `0x30``, ``0x68``, ``0x31``, ``0x0b``, ``0x30``, ``0x09``, ``0x06``, ``0x03``, ``0x55``, ``0x04``, ``0x06``, ``0x13``,` `0x02``, ``0x55``, ``0x53``, ``0x31``, ``0x25``, ``0x30``, ``0x23``, ``0x06``, ``0x03``, ``0x55``, ``0x04``, ``0x0a``,` `0x13``, ``0x1c``, ``0x53``, ``0x74``, ``0x61``, ``0x72``, ``0x66``, ``0x69``, ``0x65``, ``0x6c``, ``0x64``, ``0x20``,` `0x54``, ``0x65``, ``0x63``, ``0x68``, ``0x6e``, ``0x6f``, ``0x6c``, ``0x6f``, ``0x67``, ``0x69``, ``0x65``, ``0x73``,` `0x2c``, ``0x20``, ``0x49``, ``0x6e``, ``0x63``, ``0x2e``, ``0x31``, ``0x32``, ``0x30``, ``0x30``, ``0x06``, ``0x03``,` `0x55``, ``0x04``, ``0x0b``, ``0x13``, ``0x29``, ``0x53``, ``0x74``, ``0x61``, ``0x72``, ``0x66``, ``0x69``, ``0x65``,` `0x6c``, ``0x64``, ``0x20``, ``0x43``, ``0x6c``, ``0x61``, ``0x73``, ``0x73``, ``0x20``, ``0x32``, ``0x20``, ``0x43``,` `0x65``, ``0x72``, ``0x74``, ``0x69``, ``0x66``, ``0x69``, ``0x63``, ``0x61``, ``0x74``, ``0x69``, ``0x6f``, ``0x6e``,` `0x20``, ``0x41``, ``0x75``, ``0x74``, ``0x68``, ``0x6f``, ``0x72``, ``0x69``, ``0x74``, ``0x79``,` `};` `static` `const` `unsigned` `char` `TA_RSA_N0[] ``=` `{` `0xb7``, ``0x32``, ``0xc8``, ``0xfe``, ``0xe9``, ``0x71``, ``0xa6``, ``0x04``, ``0x85``, ``0xad``, ``0x0c``, ``0x11``,` `0x64``, ``0xdf``, ``0xce``, ``0x4d``, ``0xef``, ``0xc8``, ``0x03``, ``0x18``, ``0x87``, ``0x3f``, ``0xa1``, ``0xab``,` `0xfb``, ``0x3c``, ``0xa6``, ``0x9f``, ``0xf0``, ``0xc3``, ``0xa1``, ``0xda``, ``0xd4``, ``0xd8``, ``0x6e``, ``0x2b``,` `0x53``, ``0x90``, ``0xfb``, ``0x24``, ``0xa4``, ``0x3e``, ``0x84``, ``0xf0``, ``0x9e``, ``0xe8``, ``0x5f``, ``0xec``,` `0xe5``, ``0x27``, ``0x44``, ``0xf5``, ``0x28``, ``0xa6``, ``0x3f``, ``0x7b``, ``0xde``, ``0xe0``, ``0x2a``, ``0xf0``,` `0xc8``, ``0xaf``, ``0x53``, ``0x2f``, ``0x9e``, ``0xca``, ``0x05``, ``0x01``, ``0x93``, ``0x1e``, ``0x8f``, ``0x66``,` `0x1c``, ``0x39``, ``0xa7``, ``0x4d``, ``0xfa``, ``0x5a``, ``0xb6``, ``0x73``, ``0x04``, ``0x25``, ``0x66``, ``0xeb``,` `0x77``, ``0x7f``, ``0xe7``, ``0x59``, ``0xc6``, ``0x4a``, ``0x99``, ``0x25``, ``0x14``, ``0x54``, ``0xeb``, ``0x26``,` `0xc7``, ``0xf3``, ``0x7f``, ``0x19``, ``0xd5``, ``0x30``, ``0x70``, ``0x8f``, ``0xaf``, ``0xb0``, ``0x46``, ``0x2a``,` `0xff``, ``0xad``, ``0xeb``, ``0x29``, ``0xed``, ``0xd7``, ``0x9f``, ``0xaa``, ``0x04``, ``0x87``, ``0xa3``, ``0xd4``,` `0xf9``, ``0x89``, ``0xa5``, ``0x34``, ``0x5f``, ``0xdb``, ``0x43``, ``0x91``, ``0x82``, ``0x36``, ``0xd9``, ``0x66``,` `0x3c``, ``0xb1``, ``0xb8``, ``0xb9``, ``0x82``, ``0xfd``, ``0x9c``, ``0x3a``, ``0x3e``, ``0x10``, ``0xc8``, ``0x3b``,` `0xef``, ``0x06``, ``0x65``, ``0x66``, ``0x7a``, ``0x9b``, ``0x19``, ``0x18``, ``0x3d``, ``0xff``, ``0x71``, ``0x51``,` `0x3c``, ``0x30``, ``0x2e``, ``0x5f``, ``0xbe``, ``0x3d``, ``0x77``, ``0x73``, ``0xb2``, ``0x5d``, ``0x06``, ``0x6c``,` `0xc3``, ``0x23``, ``0x56``, ``0x9a``, ``0x2b``, ``0x85``, ``0x26``, ``0x92``, ``0x1c``, ``0xa7``, ``0x02``, ``0xb3``,` `0xe4``, ``0x3f``, ``0x0d``, ``0xaf``, ``0x08``, ``0x79``, ``0x82``, ``0xb8``, ``0x36``, ``0x3d``, ``0xea``, ``0x9c``,` `0xd3``, ``0x35``, ``0xb3``, ``0xbc``, ``0x69``, ``0xca``, ``0xf5``, ``0xcc``, ``0x9d``, ``0xe8``, ``0xfd``, ``0x64``,` `0x8d``, ``0x17``, ``0x80``, ``0x33``, ``0x6e``, ``0x5e``, ``0x4a``, ``0x5d``, ``0x99``, ``0xc9``, ``0x1e``, ``0x87``,` `0xb4``, ``0x9d``, ``0x1a``, ``0xc0``, ``0xd5``, ``0x6e``, ``0x13``, ``0x35``, ``0x23``, ``0x5e``, ``0xdf``, ``0x9b``,` `0x5f``, ``0x3d``, ``0xef``, ``0xd6``, ``0xf7``, ``0x76``, ``0xc2``, ``0xea``, ``0x3e``, ``0xbb``, ``0x78``, ``0x0d``,` `0x1c``, ``0x42``, ``0x67``, ``0x6b``, ``0x04``, ``0xd8``, ``0xf8``, ``0xd6``, ``0xda``, ``0x6f``, ``0x8b``, ``0xf2``,` `0x44``, ``0xa0``, ``0x01``, ``0xab``,` `};` `static` `const` `unsigned` `char` `TA_RSA_E0[] ``=` `{` `0x03``,` `};` `static` `const` `br_x509_trust_anchor TAs[] ``=` `{` `{` `{ (``unsigned` `char` `*``)TA_DN0, ``sizeof` `TA_DN0 },` `BR_X509_TA_CA,` `{` `BR_KEYTYPE_RSA,` `{ .rsa ``=` `{` `(``unsigned` `char` `*``)TA_RSA_N0, ``sizeof` `TA_RSA_N0,` `(``unsigned` `char` `*``)TA_RSA_E0, ``sizeof` `TA_RSA_E0,` `} }` `}` `},` `};` `#ifdef` `__cplusplus` `} ``/* extern "C" */` `#endif` `#endif` `/* ifndef _CERTIFICATES_H_ */` |
| --- | --- |

#### Add SSLClient wrapper

Now we are going to add the SSLClient library and the `trust_anchors.h` file.

| `#include` `<SPI.h>` `#include` `<EthernetLarge.h>` `#include` `<SSLClient.h>` `#include` `"trust_anchors.h"` |
| --- |

**I also changed the Ethernet library with EthernetLarge instead of the change described in the upper section.**

Then apply the wrapper `EthernetClient` with all the references of Trust Anchors. The file contains generated trust anchor array names `TAs` with length. `TAs_NUM`.

[![](https://maker.wiznet.io/upload/mirror/body/0b486ea3c55fdcd7fb15.jpg)](https://www.pcbway.com/?from=mischianti702)

| `// Choose the analog pin to get semi-random data from for SSL` `// Pick a pin that's not connected or attached to a randomish voltage source` `const` `int` `rand_pin ``=` `A5;` `// Initialize the SSL client library` `// We input an EthernetClient, our trust anchors, and the analog pin` `EthernetClient base_client;` `SSLClient client(base_client, TAs, (size_t)TAs_NUM, rand_pin);` |
| --- |

And we change the port to 443 (HTTPS).

| `// if you get a connection, report back via serial:` `if` `(client.connect(server, ``443``)) {` `Serial.print``(``"connected to "``);` `// Make a HTTP request:` `client.println(``"GET /get HTTP/1.1"``);` `client.println(``"Host: httpbin.org"``);` `client.println(``"Connection: close"``);` `client.println();` `} ``else` `{` `// if you didn't get a connection to the server:` `Serial.println``(``"connection failed"``);` `}` |
| --- |

Here is the complete sketch.

| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | `/*` `Web SSL client` `This sketch connects to a test website (httpbin.org)` `and try to do a secure GET request on port 443,` `to do the SSL request we use SSLClient with the` `site Trust Anchor` `the output is printed on Serial` `by Renzo Mischianti <www.mischianti.org>` [`https://www.mischianti.org`](https://www.mischianti.org/) `*/` `#include` `<SPI.h>` `#include` `<EthernetLarge.h>` `#include` `<SSLClient.h>` `#include` `"trust_anchors.h"` `// Enter a MAC address for your controller below.` `// Newer Ethernet shields have a MAC address printed on a sticker on the shield` `byte` `mac[] ``=` `{ ``0xDE``, ``0xAD``, ``0xBE``, ``0xEF``, ``0xFE``, ``0xED` `};` `// if you don't want to use DNS (and reduce your sketch size)` `// use the numeric IP instead of the name for the server:` `//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)` `//char server[] = "www.google.com"; // name address for Google (using DNS)` `char` `server[] ``=` `"httpbin.org"``; ``// name address for Google (using DNS)` `// Set the static IP address to use if the DHCP fails to assign` `#define` `MYIPADDR ``192``,``168``,``1``,``28` `#define` `MYIPMASK ``255``,``255``,``255``,``0` `#define` `MYDNS ``192``,``168``,``1``,``1` `#define` `MYGW ``192``,``168``,``1``,``1` `// Choose the analog pin to get semi-random data from for SSL` `// Pick a pin that's not connected or attached to a randomish voltage source` `const` `int` `rand_pin ``=` `A5;` `// Initialize the SSL client library` `// We input an EthernetClient, our trust anchors, and the analog pin` `EthernetClient base_client;` `SSLClient client(base_client, TAs, (size_t)TAs_NUM, rand_pin);` `// Variables to measure the speed` `unsigned` `long` `beginMicros, endMicros;` `unsigned` `long` `byteCount ``=` `0``;` `bool printWebData ``=` `true``; ``// set to false for better speed measurement` `void` `setup``() {` `Serial.begin``(``115200``);` `delay``(``1000``);` `Serial.println``(``"Begin Ethernet"``);` `// You can use Ethernet.init(pin) to configure the CS pin` `//Ethernet.init(10); // Most Arduino shields` `Ethernet.init(``5``); ``// MKR ETH Shield` `//Ethernet.init(0); // Teensy 2.0` `//Ethernet.init(20); // Teensy++ 2.0` `//Ethernet.init(15); // ESP8266 with Adafruit FeatherWing Ethernet` `//Ethernet.init(33); // ESP32 with Adafruit FeatherWing Ethernet` `if` `(Ethernet.begin(mac)) { ``// Dynamic IP setup` `Serial.println``(``"DHCP OK!"``);` `}``else``{` `Serial.println``(``"Failed to configure Ethernet using DHCP"``);` `// Check for Ethernet hardware present` `if` `(Ethernet.hardwareStatus() ``==` `EthernetNoHardware) {` `Serial.println``(``"Ethernet shield was not found. Sorry, can't run without hardware. :("``);` `while` `(``true``) {` `delay``(``1``); ``// do nothing, no point running without Ethernet hardware` `}` `}` `if` `(Ethernet.linkStatus() ``==` `LinkOFF) {` `Serial.println``(``"Ethernet cable is not connected."``);` `}` `IPAddress ip(MYIPADDR);` `IPAddress dns(MYDNS);` `IPAddress gw(MYGW);` `IPAddress sn(MYIPMASK);` `Ethernet.begin(mac, ip, dns, gw, sn);` `Serial.println``(``"STATIC OK!"``);` `}` `delay``(``5000``);` `Serial.print``(``"Local IP : "``);` `Serial.println``(Ethernet.localIP());` `Serial.print``(``"Subnet Mask : "``);` `Serial.println``(Ethernet.subnetMask());` `Serial.print``(``"Gateway IP : "``);` `Serial.println``(Ethernet.gatewayIP());` `Serial.print``(``"DNS Server : "``);` `Serial.println``(Ethernet.dnsServerIP());` `Serial.println``(``"Ethernet Successfully Initialized"``);` `// if you get a connection, report back via serial:` `if` `(client.connect(server, ``443``)) {` `Serial.print``(``"connected to "``);` `// Make a HTTP request:` `client.println(``"GET /get HTTP/1.1"``);` `client.println(``"Host: httpbin.org"``);` `client.println(``"Connection: close"``);` `client.println();` `} ``else` `{` `// if you didn't get a connection to the server:` `Serial.println``(``"connection failed"``);` `}` `beginMicros ``=` `micros``();` `}` `void` `loop``() {` `// if there are incoming bytes available` `// from the server, read them and print them:` `int` `len ``=` `client.available();` `if` `(len > ``0``) {` `byte` `buffer[``80``];` `if` `(len > ``80``) len ``=` `80``;` `client.read(buffer, len);` `if` `(printWebData) {` `Serial.write``(buffer, len); ``// show in the serial monitor (slows some boards)` `}` `byteCount ``=` `byteCount ``+` `len;` `}` `// if the server's disconnected, stop the client:` `if` `(``!``client.connected()) {` `endMicros ``=` `micros``();` `Serial.println``();` `Serial.println``(``"disconnecting."``);` `client.stop();` `Serial.print``(``"Received "``);` `Serial.print``(byteCount);` `Serial.print``(``" bytes in "``);` `float` `seconds ``=` `(``float``)(endMicros ``-` `beginMicros) ``/` `1000000.0``;` `Serial.print``(seconds, ``4``);` `float` `rate ``=` `(``float``)byteCount ``/` `seconds ``/` `1000.0``;` `Serial.print``(``", rate = "``);` `Serial.print``(rate);` `Serial.print``(``" kbytes/second"``);` `Serial.println``();` `// do nothing forevermore:` `while` `(``true``) {` `delay``(``1``);` `}` `}` `}` |
| --- | --- |

Now when we execute the sketch, we obtain this output.

| `Begin Ethernet` `DHCP OK!` `Local IP : 192.168.1.138` `Subnet Mask : 255.255.255.0` `Gateway IP : 192.168.1.1` `DNS Server : 192.168.1.1` `Ethernet Successfully Initialized` `connected to HTTP/1.1 200 OK` `Date: Wed, 09 Mar 2022 11:55:33 GMT` `Content-Type: application/json` `Content-Length: 198` `Connection: close` `Server: gunicorn/19.9.0` `Access-Control-Allow-Origin: *` `Access-Control-Allow-Credentials: true` `{` `"args": {},` `"headers": {` `"Host": "httpbin.org",` `"X-Amzn-Trace-Id": "Root=1-622895b5-05f3c1351d694e66175a5335"` `},` `"origin": "82.51.127.46",` `"url": "`[`https://httpbin.org/get`](https://httpbin.org/get)`"` `}` `disconnecting.` `Received 423 bytes in 0.2611, rate = 1.62 kbytes/second` |
| --- |

## Thanks

I use this SSLClient library in my EMailSender library to use Gmail SMTP server (SSL) with Ethernet. Unfortunately, SSL connections need quite a bit of resource, and only Arduino SAMD, STM32, and ESP32 have so many resources.

1. [ESP32: pinout, specs and Arduino IDE configuration](https://www.mischianti.org/2020/05/30/esp32-pinout-specs-and-arduino-ide-configuration-part-1/)

2. [ESP32: integrated SPIFFS Filesystem](https://www.mischianti.org/2020/06/04/esp32-integrated-spiffs-filesystem-part-2/)

3. [ESP32: manage multiple Serial and logging](https://www.mischianti.org/2020/09/20/esp32-manage-multiple-serial-and-logging-for-debugging-3/)

4. ESP32 practical power saving
  1. [ESP32 practical power saving: manage WiFi and CPU](https://www.mischianti.org/2020/09/09/esp32-practical-power-saving-manage-wifi-and-cpu-1/)
  2. [ESP32 practical power saving: modem and light sleep](https://www.mischianti.org/2021/03/10/esp32-power-saving-modem-and-light-sleep-2/)
  3. [ESP32 practical power saving: deep sleep and hibernation](https://www.mischianti.org/2021/03/15/esp32-practical-power-saving-deep-sleep-and-hibernation-3/)
  4. [ESP32 practical power saving: preserve data, timer and touch wake up](https://www.mischianti.org/2021/03/18/esp32-practical-power-saving-store-data-timer-and-touch-wake-up-4/)
  5. [ESP32 practical power saving: external and ULP wake up](https://www.mischianti.org/2021/03/23/esp32-practical-power-saving-preserve-gpio-status-external-and-ulp-wake-up-5/)
  6. [ESP32 practical power saving: UART and GPIO wake up](https://www.mischianti.org/2021/03/26/esp32-practical-power-saving-wake-up-from-light-sleep-via-uart-and-gpio-6/)

5. [ESP32: integrated LittleFS FileSystem](https://www.mischianti.org/it/2021/04/01/esp32-filesistem-integrato-littlefs-5/)

6. [ESP32: integrated FFat (Fat/exFAT) FileSystem](https://www.mischianti.org/2021/04/06/esp32-integrated-ffat-fat-exfat-filesystem-6/)

7. ESP32-wroom-32
  1. [ESP32-wroom-32: flash, pinout, specs and IDE configuration](https://www.mischianti.org/2021/05/30/esp32-wroom-32-esp32-s-flash-pinout-specs-and-ide-configuration-1/)

8. ESP32-CAM
  1. [ESP32-CAM: pinout, specs and Arduino IDE configuration](https://www.mischianti.org/2021/08/30/esp32-cam-pinout-specs-and-arduino-ide-configuration-1/)
  2. [ESP32-CAM: upgrade CamerWebServer with flash features](https://www.mischianti.org/2021/09/12/esp32-cam-upgrade-camerawebserver-with-flash-features-2/)

9. ESP32: use ethernet w5500 with plain (HTTP) and SSL (HTTPS)

10. ESP32: use ethernet enc28j60 with plain (HTTP) and SSL (HTTPS)

11. Firmware and OTA update management
  1. Firmware management
    1. ESP32: flash compiled firmware (.bin)
    2. ESP32: flash compiled firmware and filesystem (.bin) with GUI tools
  2. OTA update with Arduino IDE
    1. ESP32 OTA update with Arduino IDE: filesystem, firmware and password
  3. OTA update with Web Browser
    1. ESP32 OTA update with Web Browser: firmware, filesystem and authentication
    2. ESP32 OTA update with Web Browser: upload in HTTPS (SSL/TLS) with self signed certificate
    3. ESP32 OTA update with Web Browser: custom web interface
  4. Self OTA uptate from HTTP server
    1. ESP32 self OTA update firmware from server
    2. ESP32 self OTA update firmware from server with version check
    3. ESP32 self OTA update in HTTPS (SSL/TLS) with trusted self signed certificate
  5. Non standard Firmware update
    1. ESP32 firmware and filesystem update from SD card
    2. ESP32 firmware and filesystem update with FTP client

12. […]

---

Source: https://maker.wiznet.io/bruno/projects/esp32%3A-ethernet-w5500-with-plain-http-and-ssl-https/
