diff --git a/examples/WiFiWebClientWPA2Enterprise/WiFiWebClientWPA2Enterprise.ino b/examples/WiFiWebClientWPA2Enterprise/WiFiWebClientWPA2Enterprise.ino new file mode 100644 index 00000000..d8092eca --- /dev/null +++ b/examples/WiFiWebClientWPA2Enterprise/WiFiWebClientWPA2Enterprise.ino @@ -0,0 +1,135 @@ +/* + Web client using WPA2 Enterprise connection + + This sketch connects to a website (http://www.arduino.cc) + using the WiFi module. + + This example is written for a network using WPA2 Enterprise encryption. + + Circuit: + Board with NINA module (Arduino MKR WiFi 1010, MKR VIDOR 4000 and UNO WiFi Rev.2) with firmware > 1.2.4 + + created 13 July 2010 + by dlf (Metodo2 srl) + modified 31 May 2012 + by Tom Igoe + modified 14 Aug 2019 + by Martino Facchin +*/ + + +#include +#include + +#include "arduino_secrets.h" +///////please enter your sensitive data in the Secret tab/arduino_secrets.h +char ssid[] = SECRET_SSID; // your network SSID (name) +int keyIndex = 0; // your network key Index number (needed only for WEP) + +int status = WL_IDLE_STATUS; +char server[] = "www.arduino.cc"; // name address for Arduino.cc (using DNS) + +// Initialize the WiFi Client +WiFiClient client; + +// WPA2 Enterprise usage: + +// Certificates and credentials are stored in secret tab to avoid sharing them. +// For some networks (like eduroam) your configuration will simply look like +// +// #define SECRET_SSID "eduroam" +// #define SECRET_USERNAME "identity@youruniversity.domain" +// #define SECRET_PASS "yourpassword" +// +// Call WiFi.beginEnterprise(SECRET_SSID, SECRET_USERNAME, SECRET_PASS) and you should easily connect +// +// In case of more complicated networks (that require a certificate, for example) you can use +// WPA2Enterprise functions +// WPA2Enterprise.addCACertificate() , addClientCertificate(), addIdentity() ... +// and then call WiFi.begin() as usual. + +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 + } + + // Configure the wifi module to use provided WPA2 Enterprise parameters (if needed) + Serial.println("Configuring WPA2 Enterprise credentials"); + WPA2Enterprise.addCACertificate(ca_pem); + WPA2Enterprise.addClientCertificate(client_crt, client_key); + + // Check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // Don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + // Attempt to connect to Wifi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA2 enterptise network (shows as an open network). + status = WiFi.beginEnterprise(ssid, SECRET_USERNAME, SECRET_PASSWORD); + + // Wait 1 second for connection: + delay(1000); + } + Serial.println("Connected to wifi"); + printWifiStatus(); + + Serial.println("\nStarting connection to server..."); + // If you get a connection, report back via serial: + if (client.connect(server, 80)) { + Serial.println("connected to server"); + // Make a HTTP request: + client.println("GET /asciilogo.txt HTTP/1.1"); + client.println("Host: www.arduino.cc"); + client.println("Connection: close"); + client.println(); + } +} + +void loop() { + // If there are incoming bytes available + // from the server, read them and print them: + while (client.available()) { + char c = client.read(); + Serial.write(c); + } + + // If the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting from server."); + client.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 board'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/examples/WiFiWebClientWPA2Enterprise/arduino_secrets.h b/examples/WiFiWebClientWPA2Enterprise/arduino_secrets.h new file mode 100644 index 00000000..c390e4da --- /dev/null +++ b/examples/WiFiWebClientWPA2Enterprise/arduino_secrets.h @@ -0,0 +1,93 @@ +#define SECRET_SSID "" +#define SECRET_USERNAME "" +#define SECRET_PASSWORD "" + +// This certificates are completely bogus, but your own should resemble this format +// For testing, generate them using the bootstrap script in freeradius-server/raddb repository, then +// * remove the password from client key with using this command +// openssl rsa -in client.key -out client2.key # default password is "whatever" +// * slim down client certificate by just keeping the snippet between BEGIN and END (must be smaller than 4Kbytes) + +const char * ca_pem = "-----BEGIN CERTIFICATE-----\n" +"MIIE5DCCA8ygAwIBAgIJAM/ZGtauwvHrMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\n" +"VQQGEwJGUjEPMA0GA1UECAwGUmFkaXVzMRIwEAYDVQQHDAlTb21ld2hlcmUxFTAT\n" +"BgNVBAoMDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs\n" +"ZS5vcmcxJjAkBgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X\n" +"DTE4MDQyNDIxMzQ0MloXDTE5MDQyNDIxMzQ0MlowgZMxCzAJBgNVBAYTAkZSMQ8w\n" +"DQYDVQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMGA1UECgwMRXhh\n" +"bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLm9yZzEmMCQG\n" +"A1UEAwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3\n" +"DQEBAQUAA4IBDwAwggEKAoIBAQDBM2wjdTRn0OmRadONV9EZPQyUxuo9iJ6DKHkt\n" +"rGEOd1gG4gNksrsF7gWcPdCWVCO49Xba1a16U/dyBPSuF7KHMO6Hx0OHZmJvCF1W\n" +"en8BPY9ClreYAobqnHIdQRIP8R5tpXA8qZ5aZlnD5dUB8XDka0NDNEXbvmbop6PP\n" +"OaGoNGsXzWN9mk2xQqHxYgoSHPER3QH2YCsKstgD87C/jTkHmtylv6j90PUhWTOm\n" +"oIbkQG0d1f4RNxcDdcRr18wOvk62CW2+phkWWRie/Vw5Lu1dA/bGzxFV64jX5J1+\n" +"ZZ5lyL87AE6bKtJjhLuqnPIarzenhmtCuGOsTTeFKgjlKLapAgMBAAGjggE3MIIB\n" +"MzAdBgNVHQ4EFgQUSsYRmVXei6Km4z5QPSYOvz7Zu00wgcgGA1UdIwSBwDCBvYAU\n" +"SsYRmVXei6Km4z5QPSYOvz7Zu02hgZmkgZYwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\n" +"VQQIDAZSYWRpdXMxEjAQBgNVBAcMCVNvbWV3aGVyZTEVMBMGA1UECgwMRXhhbXBs\n" +"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLm9yZzEmMCQGA1UE\n" +"AwwdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCCQDP2RrWrsLx6zAPBgNV\n" +"HRMBAf8EBTADAQH/MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly93d3cuZXhhbXBs\n" +"ZS5vcmcvZXhhbXBsZV9jYS5jcmwwDQYJKoZIhvcNAQELBQADggEBAFbOEusBzXfa\n" +"0qdTw3U98t58BUxYYzScKZNjgS/MYVEdS0OaMxYyqstp8BKr8YugEHUHGDJt9k37\n" +"yXGLVUeS+ST/Xy2UvOus7bLv0YYL26tQbBs5iDy9WJ3IBUtWhfqQW/ISpfma2uvN\n" +"kFfGCV0JkPa57oR1kj0OPkOBQSXPwTbbabUdQmB+d6IZi9ZTMGLv1ogq75X5eSJP\n" +"Qi6ql9nQF6TN24DIF8XJ/D6GJPbdmoMQ18VGoRlnz37Ee82ve9I5gvJquXZjOBd4\n" +"rK7p3mrSzzkiCdjB8ehpJygmgT1U/ufE1PopES8hSkCgvQ2EsNBIGYiJUFRJfeEM\n" +"kCCZqNTTmGE=\n" +"-----END CERTIFICATE-----"; + +const char * client_crt = "-----BEGIN CERTIFICATE-----\n" +"MIIEQTCCAymgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBkjELMAkGA1UEBhMCRlIx\n" +"DzANBgNVBAgMBlJhZGl1czESMBAGA1UEBwwJU29tZXdoZXJlMRQwEgYDVQQKDAtF\n" +"eGFtcGxlIEluYzEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5vcmcxJjAk\n" +"BgNVBAMMHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE5MDgxMjE0\n" +"MTEyMVoXDTE5MTAxMTE0MTEyMVowdDELMAkGA1UEBhMCRlIxDzANBgNVBAgMBlJh\n" +"ZGl1czEUMBIGA1UECgwLRXhhbXBsZSBJbmMxFTATBgNVBAMMDEV4YW1wbGUgdXNl\n" +"cjEnMCUGCSqGSIb3DQEJARYYdXNlci5leGFtcGxlQGV4YW1wbGUub3JnMIIBIjAN\n" +"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtaiggI1w7wez/DjYM+F1RDUMa73J\n" +"07+XZM1OxQuRt8hbwh8wod1Bmu3iFtsSnzssygeek/9+Vd6gXqW5jBa4sMz0CQM1\n" +"PkIjBsgjPaKk98c2tyDYqA+nz0Wi9JOkAKPQwTTDijsAF3QfgcGvWZJngjHkeKoz\n" +"1BLJehDO4wOu1z3kB8CQGWQ0hZW2Sjt+qFqDTXt8Q0GF+nehqx7juHw/e6QDNiuH\n" +"Xmf0adJWUzFeMnQewUDD5R3EBLUiWzKbRFxoi0qs/tM1IUPQ0fASHcJMwZllCZpa\n" +"3B9nxAhLScR8RjDU0d0F+3hQGNKShJyvvR6dM2Qzie8H2yA7QrLdRX8XywIDAQAB\n" +"o4G+MIG7MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoGCCsGAQUF\n" +"BwMCMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhh\n" +"bXBsZV9jYS5jcmwwNwYIKwYBBQUHAQEEKzApMCcGCCsGAQUFBzABhhtodHRwOi8v\n" +"d3d3LmV4YW1wbGUub3JnL29jc3AwGwYDVR0RBBQwEoEQdXNlckBleGFtcGxlLm9y\n" +"ZzANBgkqhkiG9w0BAQsFAAOCAQEAVC05K4XqjfjoTgQeB7FtjDUiuQedbNi3z3Sy\n" +"2qZVqgaYa+z9cijrL6Z7Z5BvM+JWUxfPjiXXF6M/j1QeyNLKtieDusO/yUaQTmSz\n" +"fyYbdXNlGBzsMLGMgp+xComZ5ZUQQwsmx8phagWqNlzAnQuLyyRshj+hOYjmysXs\n" +"2V6SUfRMEdgr57hRREHZBjJq/PQZL0Kw7BiXMYhMfFJfe1Z4LBYhRqAPDWVoPI1j\n" +"MNXM6X7R5zSNRbrj9biT4WNLBDooDW4Bzz1cimLock/nCY+TTj8Xoy/0szqkIdps\n" +"G1SM9dB7SdXDW6DewvRK28+9xe6HG4xsLtNNYFWqhPkF5S4BIg==\n" +"-----END CERTIFICATE-----"; + +const char * client_key = "-----BEGIN RSA PRIVATE KEY-----\n" +"MIIEpAIBAAKCAQEAtaiggI1w7wez/DjYM+F1RDUMa73J07+XZM1OxQuRt8hbwh8w\n" +"od1Bmu3iFtsSnzssygeek/9+Vd6gXqW5jBa4sMz0CQM1PkIjBsgjPaKk98c2tyDY\n" +"qA+nz0Wi9JOkAKPQwTTDijsAF3QfgcGvWZJngjHkeKoz1BLJehDO4wOu1z3kB8CQ\n" +"GWQ0hZW2Sjt+qFqDTXt8Q0GF+nehqx7juHw/e6QDNiuHXmf0adJWUzFeMnQewUDD\n" +"5R3EBLUiWzKbRFxoi0qs/tM1IUPQ0fASHcJMwZllCZpa3B9nxAhLScR8RjDU0d0F\n" +"+3hQGNKShJyvvR6dM2Qzie8H2yA7QrLdRX8XywIDAQABAoIBABl0MmEw8HUd0DN0\n" +"R58lZUgUYtQp+MDJ5M3EEth7YYSt92WA91CG7y1lTbvEIJzdLs50ON0l/K7Njg0V\n" +"DaW6fVCQt1UX9PrvS3ckzgNR6emqKVmJqbIK14msiUPZ+C36xkJ8QTX6RG4E4HFP\n" +"EWHsqMJOeWQK/U4m/8Ix3rtihbo0/ihfkc31HeLMqOzomf3d4XNxg9idmEPYpFrC\n" +"XlusQTql6FCC8hKeayPcETVQ1x7iu2rg6zhKNmfosAUYuefCRA4KUvHbwkjwwpwh\n" +"em76wMDGY5T06orFn13bQ2b3qP9aptK9Bj8lY3BQEkqKAHcAPf+31l5UZbcUStTg\n" +"PrFD8AECgYEA7dNZav257Naqg2qGt157ILukRIdCj8BqCq7awzlJQ7dNAO9zPEBf\n" +"cKEJAN3hrlJsT72lWkbGoLUGUGLmL+jUR2VP80+ETEeCxU/EErue6SRyXHC7triY\n" +"4VGX8vmUtdeeOEyl+2QcIgwldQL0skyKl69GzKeH+mQbXtA+IXmEH8sCgYEAw4p3\n" +"+mKIPu6alZm3/LeEzUavApiUP+w/0dLnSpAhs7vjn+Jv2eQBm5ymg0dBkZuRNXmh\n" +"p4dik4PlILPITq+T9GyVMg4g0utX9Xz78uGlKrNzWj2yMLv0o0l4FnW8aykHIoRi\n" +"B2+zTxfB3gMckvJ++VWs4q8kZWCpM7onsSIh6AECgYEArHvrTyCDttSdyD/7QoSA\n" +"kmXkplrfGHj5r5PPT2V90GHhtDr1/Y3Gal4wtHM32YEn0tF9WjMYnbeMw8Jmpfqb\n" +"8sf0q0dRcS0wF8BZOSjgAMERPB/61HOfVVMi+/KtOxENTFGy09dwW/UpOWsSYzoG\n" +"DiruE0Gx6hSukR5A4XBLNe8CgYBjyrjsOXja1R5jFq4E9Qt7T4VlR8Tw0nrHdGDB\n" +"dskcVtkV8ZOvmWMQrWN1P9pAmyoCJm7PdpJiQj+e7uFc9tIFPZzujLNHsP+UsxJJ\n" +"o8qM/kPyW+YiZOm2o3n7zF46OhgAD5uPu/vAc5lm2iOtAsC2MnkmvsdOTYRMd8Zl\n" +"6ctwAQKBgQDe0tEm8EkIIwHm/yYpkGb3NXA/e+SM8o1Qcpl1N3A9yfU+dPxklLXE\n" +"rFfELDn3vi26KPhoE1d7hOr6Goy/63Mryp+4VKNEKspDnqWvECr/oMeANu0qNRtn\n" +"YVD6e1rWtZe007GVQfM+HJD9AFHSRwdAsrLNDDe8l7S984C/2ua5kg==\n" +"-----END RSA PRIVATE KEY-----"; diff --git a/src/WiFi.cpp b/src/WiFi.cpp index e4a34dd4..1e8123b6 100644 --- a/src/WiFi.cpp +++ b/src/WiFi.cpp @@ -27,6 +27,18 @@ extern "C" { #include "utility/debug.h" } +void WPA2EnterpriseClass::addCACertificate(const char* ca_pem) { + WiFiDrv::wpa2EntSetCACertificate(ca_pem); +} + +void WPA2EnterpriseClass::addClientCertificate(const char* client_crt, const char* client_key) { + // TODO: make sure that client_crt is not bigger tahn 4050bytes + WiFiDrv::wpa2EntSetClientCertificate(client_crt, client_key); +} + +// singleton +WPA2EnterpriseClass WPA2Enterprise; + WiFiClass::WiFiClass() : _timeout(50000) { } @@ -156,6 +168,15 @@ uint8_t WiFiClass::beginAP(const char *ssid, const char* passphrase, uint8_t cha return status; } +int WiFiClass::beginEnterprise(const char *ssid, const char* username, const char* password) +{ + WiFiDrv::wpa2EntSetIdentity(username); + WiFiDrv::wpa2EntSetUsername(username); + WiFiDrv::wpa2EntSetPassword(password); + WiFiDrv::wpa2EntEnable(); + return begin(ssid); +} + void WiFiClass::config(IPAddress local_ip) { WiFiDrv::config(1, (uint32_t)local_ip, 0, 0); diff --git a/src/WiFi.h b/src/WiFi.h index 3bb5db60..5094d0a2 100644 --- a/src/WiFi.h +++ b/src/WiFi.h @@ -35,6 +35,23 @@ extern "C" { #include "WiFiSSLClient.h" #include "WiFiServer.h" +typedef enum _eap_methods { + EAP_TLS = 0, + EAP_PEAP = 1, + EAP_TTLS = 2, +} eap_method; + +class WPA2EnterpriseClass +{ +public: + void clear(); + void save(); + void addCACertificate(const char* ca_pem); + void addClientCertificate(const char* client_crt, const char* client_key); +}; + +extern WPA2EnterpriseClass WPA2Enterprise; + class WiFiClass { private: @@ -80,6 +97,14 @@ class WiFiClass uint8_t beginAP(const char *ssid, const char* passphrase); uint8_t beginAP(const char *ssid, const char* passphrase, uint8_t channel); + /* Start Wifi connection with wpa2 enterprise + * + * helper function for most university WPA2 connections + * if a fine-grained configuration is needed (like adding certificates) + * use WPA2Enterprise functions and then call begin() normally + */ + int beginEnterprise(const char *ssid, const char* username, const char* password); + /* Change Ip configuration settings disabling the dhcp client * * param local_ip: Static ip configuration diff --git a/src/utility/wifi_drv.cpp b/src/utility/wifi_drv.cpp index 3575d797..511bf176 100644 --- a/src/utility/wifi_drv.cpp +++ b/src/utility/wifi_drv.cpp @@ -1078,4 +1078,178 @@ void WiFiDrv::analogWrite(uint8_t pin, uint8_t value) SpiDrv::spiSlaveDeselect(); } +void WiFiDrv::wpa2EntSetIdentity(const char* identity) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(WPA2_ENTERPRISE_SET_IDENTITY, PARAM_NUMS_1); + SpiDrv::sendParam((uint8_t*)identity, strlen(identity), LAST_PARAM); + + // pad to multiple of 4 + int commandSize = 5 + strlen(identity); + while (commandSize % 4) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(WPA2_ENTERPRISE_SET_IDENTITY, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::wpa2EntSetPassword(const char* password) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(WPA2_ENTERPRISE_SET_PASSWORD, PARAM_NUMS_1); + SpiDrv::sendParam((uint8_t*)password, strlen(password), LAST_PARAM); + + // pad to multiple of 4 + int commandSize = 5 + strlen(password); + while (commandSize % 4) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(WPA2_ENTERPRISE_SET_PASSWORD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::wpa2EntSetUsername(const char* username) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(WPA2_ENTERPRISE_SET_USERNAME, PARAM_NUMS_1); + SpiDrv::sendParam((uint8_t*)username, strlen(username), LAST_PARAM); + + // pad to multiple of 4 + int commandSize = 5 + strlen(username); + while (commandSize % 4) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(WPA2_ENTERPRISE_SET_USERNAME, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::wpa2EntSetClientCertificate(const char* client_crt, const char* client_key) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(WPA2_ENTERPRISE_SET_CERT_KEY, PARAM_NUMS_2); + SpiDrv::sendParamLen16(strlen(client_crt)); + SpiDrv::sendParamLen16(strlen(client_key)); + SpiDrv::sendParamNoLen((uint8_t*)client_crt, strlen(client_crt), NO_LAST_PARAM); + SpiDrv::sendParamNoLen((uint8_t*)client_key, strlen(client_key), LAST_PARAM); + + // pad to multiple of 4 + int commandSize = 5 + strlen(client_crt) + strlen(client_key); + while (commandSize % 4) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(WPA2_ENTERPRISE_SET_CERT_KEY, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::wpa2EntSetCACertificate(const char* ca_pem) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(WPA2_ENTERPRISE_SET_CA_CERT, PARAM_NUMS_1); + SpiDrv::sendParamLen16(strlen(ca_pem)); + SpiDrv::sendParamNoLen((uint8_t*)ca_pem, strlen(ca_pem), LAST_PARAM); + + // pad to multiple of 4 + int commandSize = 5 + strlen(ca_pem); + while (commandSize % 4) { + SpiDrv::readChar(); + commandSize++; + } + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(WPA2_ENTERPRISE_SET_CA_CERT, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::wpa2EntEnable() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(WPA2_ENTERPRISE_ENABLE, PARAM_NUMS_0); + + SpiDrv::spiSlaveDeselect(); + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + SpiDrv::spiSlaveSelect(); + + // Wait for reply + uint8_t _data = 1; + uint8_t _dataLen = 0; + SpiDrv::waitResponseCmd(WPA2_ENTERPRISE_ENABLE, PARAM_NUMS_1, &_data, &_dataLen); + + SpiDrv::spiSlaveDeselect(); +} + WiFiDrv wiFiDrv; diff --git a/src/utility/wifi_drv.h b/src/utility/wifi_drv.h index d9bfeff2..80e671f1 100644 --- a/src/utility/wifi_drv.h +++ b/src/utility/wifi_drv.h @@ -286,6 +286,13 @@ class WiFiDrv static void digitalWrite(uint8_t pin, uint8_t value); static void analogWrite(uint8_t pin, uint8_t value); + static void wpa2EntSetIdentity(const char* identity); + static void wpa2EntSetUsername(const char* username); + static void wpa2EntSetPassword(const char* password); + static void wpa2EntSetCACertificate(const char* ca_pem); + static void wpa2EntSetClientCertificate(const char* client_crt, const char* client_key); + static void wpa2EntEnable(); + friend class WiFiUDP; friend class WiFiClient; }; diff --git a/src/utility/wifi_spi.h b/src/utility/wifi_spi.h index 7402e434..b3fcba8b 100644 --- a/src/utility/wifi_spi.h +++ b/src/utility/wifi_spi.h @@ -97,6 +97,14 @@ enum { GET_DATABUF_TCP_CMD = 0x45, INSERT_DATABUF_CMD = 0x46, + // wpa2 enterprise commands + WPA2_ENTERPRISE_SET_IDENTITY = 0x4A, + WPA2_ENTERPRISE_SET_USERNAME = 0x4B, + WPA2_ENTERPRISE_SET_PASSWORD = 0x4C, + WPA2_ENTERPRISE_SET_CA_CERT = 0x4D, + WPA2_ENTERPRISE_SET_CERT_KEY = 0x4E, + WPA2_ENTERPRISE_ENABLE = 0x4F, + // regular format commands SET_PIN_MODE = 0x50, SET_DIGITAL_WRITE = 0x51,