Establishing a test environment for WPA2 Enterprise

Ahead of availability of support for WPA/WPA2 Enterprise security for the Gen3 devices, I am still trying to get my Photons now on Device OS 1.1.0 to connect to a test environment to mimic the one outlined by @BDub that consists of FreeRadius server running on a Raspberry Pi and using a Unifi AP AC Pro. I have been following the setup instructions posted June 17 and have hit a few problems.

Problem 1. If you install FreeRadius now it is version 3.0 and it installs into a different directory than indicated in the instructions - that is now overcome.
Problem 2. The instructions at step 10. call for editing of the eap.conf file. When I tried this there was no existing file. A search for this issue indicates that the file needs to be copied from the /mods-available folder and renamed eap.conf - that is now overcome.
Problem 3. The instructions within step 10 are vague about exactly where in the eap.conf file the definition of certdir, certdir2 and cadir should be made? I have guessed this and it is not working. Would anyone be able to share a working eap.conf file I could copy? [Edit] I have been able with support from the freeRadius.org support group to setup the freeRadius server to authorise as per the test case below.

The rest of the setup is fine - the end result is that when I attempt to connect using WPA2 Enterprise, PEAP/MSCHAPv2 with just username and password (and no certificate) I get a WICED error of 1006 returned and the debugging mode for freeradius shows that EAP/MSCHAP authorisation failed which supports the log handler output on the device. I can provide more details of where it has failed but this is a long and difficult to read log. [Edit] I can access the internet using the AP with PEAP/MSCHAPv2 authorisation using an iPhone. So I know it is working. The Photon is a different story - the WICED error code is now 1064 EAPOL_KEY_FAILURE. The freeRadius server debug output is showing that it has authorised access MSCHAP2: SUCCESS but then the authorisation session is terminated by the Photon.

Conclusion: WPA2 Enterprise security does not work on Device OS 1.1.0 - there is insufficient output from the Log on the Photon to determine exactly what is going wrong. What is rather worrying is that this is meant to be a copy of the regression tests performed by Particle - that are supposed to work!!

I’m a little confused with the timing of your post and your edits here. So your AP seems to be properly configured now but you are just trying to get the Photon to connect? Can you share more about how you are configuring the Photon’s credentials and / or share the related code? You mention two different errors - which one is happening, and what did you change between the two?

Things always fail for a reason, and while there are bugs, usually the reason involves a user code error or a mismatch in assumptions / expectations. A conclusion that WPA2 Enterprise does not work doesn’t seem to be accurate given that it seems to have been working for most people that have used it since v0.7.0. More info is needed for folks to be able to make recommendations.

If the Photon is terminating the session related to a key failure, try looking in the system firmware for the place where that error is generated. That may give you more insight into what may be wrong so that you can fix it. Edit: looked it up, and comments say “Unknown failure occurred during the EAPOL key handshake” Is it possible there is some kind of configuration mismatch that is causing the Photon to reject the response? I’m no Enterprise Wifi expert, so I could be totally off base.

Thanks for replying. The timing is simple - I posted originally to see if anyone in the Particle Community could help. I didn’t any response by the time I received a reply on the freeRadius support group - I then got the freeRadius server working - in that I can log on to the WAP using WPA2 Enterprise security with just a username and password (so the simplest level of PEAP/MSCHAPv2) using an iphone, a mac but not a Photon.

I am just following the test instructions posted by Particle and provided by Brett. I understood that these are now being used for each release? I have tried via the CLI and serial terminal W command and with a test application. I agree that things always fail for a reason. For some reason the photon is ending the authorisation session - timeout? Everything looks good on the freeRadius server log output. I was rather hoping that I could get a tiny bit of expert input from Andrey or Brett. The standard logging output from the photon is really just giving the failure described. Happy to share below the test application:

SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);

#define ENTSECTLS   false
#define ENTSECPEAP  true
#define CERTIFICATE false
#define WPA2SEC     false

#if ENTSECTLS
#define TEST_SSID "Entwpa2"
#define TEST_UNAM "test"
#define TEST_UPWD "123456"
#define ENT_SEC_TYPE WPA2_ENTERPRISE
#define EAP_TYPE WLAN_EAP_TYPE_TLS
#define SEC_CIPHER WLAN_CIPHER_AES
#elif ENTSECPEAP
#define TEST_SSID "Entwpa2"
#define TEST_UNAM "particle"
#define TEST_UPWD "particle2017"
#define TEST_OUTR "particle"                    //"anonymous"
#define ENT_SEC_TYPE WPA2_ENTERPRISE
#define EAP_TYPE WLAN_EAP_TYPE_PEAP
#define SEC_CIPHER WLAN_CIPHER_AES
#elif WPA2SEC
#define TEST_SSID "testwpa2"
#define TEST_UPWD "testwpa2"
#define ENT_SEC_TYPE WPA2
#define SEC_CIPHER WLAN_CIPHER_AES
#endif

SerialLogHandler logHandler(115200, LOG_LEVEL_ALL);

bool isConnectOnce;
bool hasTriedConnectOnce;
byte mac[6];
uint32_t ms;
#if CERTIFICATE
const char root_ca_cert[] = {"-----BEGIN CERTIFICATE-----END CERTIFICATE-----\r\n\r\n"};
#endif
void setup()
{
    Serial.begin(115200);
    while (!Serial.available()) delay(100);
    Serial.println("WPA Enterprise WiFi Credentials Test");
    //
    Serial.println("Step 1: Turn On Wifi module and confirm MAC address ");
    isConnectOnce = false;
    hasTriedConnectOnce = false;
    WiFi.on();
    //
    WiFi.macAddress(mac);
    for (int i=0; i<6; i++) {Serial.printf("%02x%s", mac[i], i != 5 ? ":" : "");}
    Serial.println("");
    //
    Serial.println("Step 2: Clear WAP credentials if they exist");
    if (WiFi.hasCredentials())
    {
        Serial.println("Device has existing WAP credentials stored - delete these");
        if (WiFi.clearCredentials())    {Serial.println("Device WAP credentials cleared successfully");}
        else                            {Serial.println("Device WAP credentials not cleared");}
    }
    else
    {
        Serial.println("Device has no WAP credentials currently");
    }
    //
    Serial.println("Step 3: Set WiFi credentials");
    #if ENTSECTLS                                                   //WPA2 Enterprise with EAP-TLS
        WiFiCredentials credentials(TEST_SSID, ENT_SEC_TYPE);       //SSID and credentials type
        Serial.printlnf("Set SSID : %s Security Type: %s", TEST_SSID, ENT_SEC_TYPE == WPA2_ENTERPRISE ?"WPA2_ENTERPRISE":"WPA2");
        credentials.setEapType(WLAN_EAP_TYPE_TLS);                  //EAP type: EAP-TLS
        Serial.printlnf("Set EAP type : %s", EAP_TYPE == WLAN_EAP_TYPE_TLS?"EAP/TLS":"PEAP/MSCHAP");
        //credentials.setCipher(SEC_CIPHER);                          //Should not be required
        //Serial.printlnf("Set Cipher : AES");
        credentials.setIdentity(TEST_UNAM);                         //Set username
        Serial.printlnf("Set Username to : %s", TEST_UNAM);
        credentials.setPassword(TEST_UPWD);                         //Set password
        Serial.printlnf("Set Password to : %s", TEST_UPWD);
        credentials.setClientCertificate(root_ca_cert);             //Client certificate in PEM format
        Serial.printlnf("Set Client Certificate: %s", root_ca_cert);
        credentials.setPrivateKey(root_ca_cert);                    //Private key in PEM format - not clear what this is/client certificate tried
        //credentials.setRootCertificate(root_ca_cert);               //Root (CA) certificate in PEM format (optional)
        credentials.setOuterIdentity("anonymous");                  //EAP outer identity (optional, default - "anonymous")
        WiFi.setCredentials(credentials);                           //Save credentials
        Serial.println("Credentials set for WPA2 Enterprise EAP/TLS");
    #elif ENTSECPEAP                                                //WPA2 Enterprise with PEAP/MSCHAPv2
        WiFiCredentials credentials(TEST_SSID, ENT_SEC_TYPE);       //SSID and credentials type
        Serial.printlnf("Set SSID : %s Security Type: %s", TEST_SSID, ENT_SEC_TYPE == WPA2_ENTERPRISE ?"WPA2_ENTERPRISE":"WPA2");
        credentials.setEapType(WLAN_EAP_TYPE_PEAP);                 //EAP type: PEAP/MSCHAPv2
        Serial.printlnf("Set EAP type : %s", EAP_TYPE == WLAN_EAP_TYPE_TLS?"EAP/TLS":"PEAP/MSCHAP");
        //credentials.setCipher(SEC_CIPHER);                          //Should not be required
        //Serial.printlnf("Set Cipher : AES");
        credentials.setIdentity(TEST_UNAM);                         //Set username
        Serial.printlnf("Set Username to : %s", TEST_UNAM);
        credentials.setPassword(TEST_UPWD);                         //Set password
        Serial.printlnf("Set Password to : %s", TEST_UPWD);
        credentials.setOuterIdentity(TEST_OUTR);                    //Set outer identity (optional, default - "anonymous")
        Serial.printlnf("Set Outer Identity to : %s", TEST_OUTR);
        #if CERTIFICATE
        credentials.setClientCertificate(root_ca_cert);             //Set the Root Certificate
        Serial.printlnf("Set Root Certificate: %s", root_ca_cert);
        #endif
        WiFi.setCredentials(credentials);            
        Serial.println("Credentials set for WPA2 Enterprise PEAP/MSCHAPv2");
    #elif WPA2SEC
    WiFi.setCredentials(TEST_SSID, TEST_UPWD, ENT_SEC_TYPE, SEC_CIPHER);
    Serial.println("Credentials set for WPA2");
    #endif
    //
    delay(500);
    //
    if (WiFi.hasCredentials())
    {
        Serial.println("Device has new WAP credentials stored");
    }
    else
    {
        Serial.println("Device error WAP credentials not stored");
    }
    delay(2000);
    Serial.println("Step 4: Connect to WAP");
    WiFi.connect();
    if (WiFi.connecting()) Serial.println("Connecting");
    waitFor(WiFi.ready, 20000);      //wait for connected or timeout 20 seconds
    if (WiFi.ready())
    {
        Serial.println("Network Connection successful");
        if (!hasTriedConnectOnce)
        {
            hasTriedConnectOnce = true;
            Particle.connect();
        }
        waitFor(Particle.connected, 10000);
        if (Particle.connected())
        {
        Serial.println("Cloud Connection successful");
        }
    }
    else
    {
        Serial.println("Network Connection unsuccessful");
    }
}
//
void loop()
{
}

Same issue… Freeradius is working well for Linux on a laptop, multiple Android and apple phones, and iPads.

Did you ever find a solution?

There may be more issues out there but the problem I experienced with being unable to connect to an AP with WPA2 Enterprise is to do with the version of TLS. I received a test OS build from Particle support late August which I tested and returned the logs. Both versions of the OS build worked and accessed the AP with a FreeRadius server running on a RPi3. Simply - TLS1.0 and TLS1.1 work but TLS1.2 does not. For some reason the WICED software was trying to use TLS1.2. I am waiting to hear back when a fix or enhancement will be included in an OS build that allows the version of TLS to be specified along with the credentials. There may be another issue related to parsing of the PEM CA certificate - although both options worked in my tests. I am not clear what are the next steps with this issue.

Conclusion: we are closer to having WPA Enterprise working - at least I have now seen a photon connected and breathing cyan!