diff --git a/examples/extras/WiFiSSLClientNoSNI/WiFiSSLClientNoSNI.ino b/examples/extras/WiFiSSLClientNoSNI/WiFiSSLClientNoSNI.ino new file mode 100644 index 0000000..58476f4 --- /dev/null +++ b/examples/extras/WiFiSSLClientNoSNI/WiFiSSLClientNoSNI.ino @@ -0,0 +1,136 @@ +/* + This example creates a client object that connects and transfers + data using always TLS but with Server Name Indication check disabled. + + WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + WARNING WARNING + WARNING This can be useful when testing initial server configurations but makes WARNING + WARNING it possible for a malicious third party to impersonate your server WARNING + WARNING through DNS spoofing, for example. WARNING + WARNING WARNING + WARNING USE THIS OPTION IN TESTING ONLY WARNING + WARNING WARNING + WARNING If you need to resort to using this option in a production environment, WARNING + WARNING your setup is at fault and there is no point using encryption. WARNING + WARNING WARNING + WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + + It is compatible with the methods normally related to plain + connections, like client.connect(host, port). + + Written by Arturo Guadalupi + Modified by Giampaolo Mancini + last revision May 2020 + +*/ + +#include +#include +#include + +char ssid[] = "yourNetwork"; // your network SSID (name) +char pass[] = "secretPassword"; // your network password (use for WPA, or use as key for WEP) +int keyIndex = 0; // your network key Index number (needed only for WEP) + +int status = WL_IDLE_STATUS; +// 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(192,168,1,1); // numeric IP for testing server (no DNS) +char server[] = "192.168.1.1"; // name address for testing server (using DNS) + +// 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): +WiFiClient client; +BearSSLClient sslClient(client); + +unsigned long getTime() { + return WiFi.getTime(); +} + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the presence of the shield: + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue: + while (true); + } + + // attempt to connect to WiFi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 10 seconds for connection: + delay(10000); + } + Serial.println("Connected to wifi"); + printWiFiStatus(); + + ArduinoBearSSL.onGetTime(getTime); + + // Disable Server Name Indication: + // for testing purposes only + // DO NOT USE IN PRODUCTION + sslClient.setInsecure(BearSSLClient::SNI::Insecure); + + Serial.println("\nStarting connection to server..."); + // if you get a connection, report back via serial: + if (sslClient.connect(server, 443)) { + Serial.println("connected to server"); + // Make a HTTP request: + sslClient.println("GET /search?q=arduino HTTP/1.1"); + sslClient.println("Host: www.google.com"); + sslClient.println("Connection: close"); + sslClient.println(); + } +} + +void loop() { + // if there are incoming bytes available + // from the server, read them and print them: + while (sslClient.available()) { + char c = sslClient.read(); + Serial.write(c); + } + + // if the server's disconnected, stop the client: + if (!sslClient.connected()) { + Serial.println(); + Serial.println("disconnecting from server."); + sslClient.stop(); + + // do nothing forevermore: + while (true); + } +} + + +void printWiFiStatus() { + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your WiFi shield's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} diff --git a/src/BearSSLClient.cpp b/src/BearSSLClient.cpp index ecd5ac3..6c177f0 100644 --- a/src/BearSSLClient.cpp +++ b/src/BearSSLClient.cpp @@ -31,25 +31,15 @@ #include "BearSSLClient.h" BearSSLClient::BearSSLClient(Client& client) : - BearSSLClient(client, TAs, TAs_NUM, false) -{ -} - -BearSSLClient::BearSSLClient(Client& client, bool noSNI) : - BearSSLClient(client, TAs, TAs_NUM, noSNI) + BearSSLClient(client, TAs, TAs_NUM) { } BearSSLClient::BearSSLClient(Client& client, const br_x509_trust_anchor* myTAs, int myNumTAs) : - BearSSLClient(client, myTAs, myNumTAs, false) -{ -} - -BearSSLClient::BearSSLClient(Client& client, const br_x509_trust_anchor* myTAs, int myNumTAs, bool noSNI) : _client(&client), _TAs(myTAs), _numTAs(myNumTAs), - _noSNI(noSNI) + _noSNI(false) { _ecKey.curve = 0; _ecKey.x = NULL; @@ -189,6 +179,14 @@ BearSSLClient::operator bool() return (*_client); } +void BearSSLClient::setInsecure(SNI insecure) +{ + switch (insecure) { + case SNI::Insecure : _noSNI = true; break; + default: _noSNI = false; + } +} + void BearSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLength) { // HACK: put the key slot info. in the br_ec_private_key structure diff --git a/src/BearSSLClient.h b/src/BearSSLClient.h index 191bfe3..a59202b 100644 --- a/src/BearSSLClient.h +++ b/src/BearSSLClient.h @@ -42,9 +42,7 @@ class BearSSLClient : public Client { public: BearSSLClient(Client& client); - BearSSLClient(Client& client, bool noSNI); BearSSLClient(Client& client, const br_x509_trust_anchor* myTAs, int myNumTAs); - BearSSLClient(Client& client, const br_x509_trust_anchor* myTAs, int myNumTAs, bool noSNI); virtual ~BearSSLClient(); virtual int connect(IPAddress ip, uint16_t port); @@ -62,6 +60,12 @@ class BearSSLClient : public Client { using Print::write; + enum class SNI { + Insecure + }; + + void setInsecure(SNI insecure) __attribute__((deprecated("INSECURE. DO NOT USE IN PRODUCTION"))); + void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength); void setEccSlot(int ecc508KeySlot, const char cert[]);