nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.36k stars 710 forks source link

BLE Static Password ー During an ESP32 ⇔ iPhone pairing, even if wrong password the connection is not terminated #1003

Open d0natz opened 4 years ago

d0natz commented 4 years ago

Hi people,

I am a newbie, and I am using Adruino IDE to test ESP32 Bluetooth .

Currently, I am using the codes here: https://github.com/nkolban/esp32-snippets/issues/793#issuecomment-458947313. Based on my test observations:

There are no problems. If a wrong password is intentionally keyed-in during bluetooth pairing, the initial bluetooth connection will eventually be terminated.

With this... I would like to know, if there is a flag or a function that would tell that the password authentication / pairing is not successful. My idea is to terminate the connect once the pairing is not successful. Below is a onConnect/onDisconnect sample sketch, and I am assuming there is a some sort of PasswordAuthenticationSuccessful version of this.

bool deviceConnected = false;

class MyServerCallbacks : public BLEServerCallbacks { void onConnect (BLEserver pServer) { deviceConnected = true; }; void onDisconnect (BLEserver pServer) { deviceConnected = false; }; }

void loop () { if (deviceConnected) { //write code here } else if (!deviceConnected) { //write code here } }

Hoping for someone's advice...

chegewara commented 4 years ago

One of those or both should return false:

  bool onConfirmPIN(uint32_t pass_key){
        ESP_LOGI(LOG_TAG, "The passkey YES/NO number:%d", pass_key);
      vTaskDelay(5000);
    return true;
  }
  bool onSecurityRequest(){
      ESP_LOGI(LOG_TAG, "SecurityRequest");
    return true;
  }
d0natz commented 4 years ago

Mr. Chegewara, Thanks for the advice.

I worked around with your advice, and lead me with authentication flag that i needed, as shown below:

bool pairingSuccess = false;

class MySecurity : public BLESecurityCallbacks {  
      void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl){
              ESP_LOGI(LOG_TAG, "Starting BLE work!");
               if(cmpl.success){pairingSuccess = true; }
               else if (!cmpl.success){pairingSuccess = false; }
     }};

void loop() {
        if (pairingSuccess) {  //write code here }
        else if (!pairingSuccess){   //write code here }
        }

However, it seems that forcing a BLEserver disconnect is not so easy for a beginner after all. I was able to come across a code for this function. ↠ ESPRESSIF: How to force client to disconnect It requires a revision of the BLEserver.ccp file. However, since this forum was in 2018, I am wondering if there is a more arduino native way for this.

/*
 *added a function on BLEServer.cpp to add the disconnection feature
 *Force a client to disconnect
 */
void BLEServer::disconnectClient() {
    ESP_LOGD(LOG_TAG, ">> disconnectClient()");
    esp_err_t errRc = ::esp_ble_gatts_close(getGattsIf(), getConnId());
    if (errRc != ESP_OK) {
        ESP_LOGE(LOG_TAG, "esp_ble_gatts_close: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
        return;
    }
    ESP_LOGD(LOG_TAG, "<< disconnectClient()");
} // disconnectClient
void loop() {
        if (condition){ pServer->disconnectClient() ;
      }
}

Again, hoping for someone's advice...

chegewara commented 4 years ago

My idea was to show you that you can send false from security callback which means esp32 refused/failed to authenticate.

Also, in my understanding esp-idf low level library should disconnect if authentication failed, but here i might be wrong and i should check bluetooth specs to what are requirements.

In theory not being authenticated is not end of world yet, because in some cases (many cases actually) some characteristics can be allowed to red/write without authentication and you may want to protect just few. That way it would be wrong if low level library would decide to disconnect if authentication failed.

d0natz commented 4 years ago

Mr. Chegewara, Again, thanks for the advice.

My idea wa to show you hat you can send false from security callback which means esp32 refused/failed to authenticate.

Sorry for my slow comprehension... In your statement above, are you referring to my ISSUE#1ーPassword Authentication Flag or ISSUE#2ーDisconnection Command?

By the way... For my ISSUE#2, I still haven't found a way to control how to terminate the BLE connection. I am just using either one of the below commands:

BLEDevice::deinit(false);

//or

ESP.restart();

Is there a more precise "arduinoish" command just for BLE disconnection?

chegewara commented 4 years ago

In your statement above, are you referring to my ISSUE#1ーPassword Authentication Flag

It was about issue 1

For issue 2 you could try this: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEServer.cpp#L426

d0natz commented 4 years ago

Mr. Chegewara, Again, thanks for your advice.

My idea wa to show you hat you can send false from security callback which means esp32 refused/failed to authenticate.

If the above is for ISSUE#1, are you advising that, if I change the return from true ➝ false in either or both of the snippets below, a failed authentication would lead to an automatic termination of the BLE connection?

  bool onConfirmPIN(uint32_t pass_key){
        ESP_LOGI(LOG_TAG, "The passkey YES/NO number:%d", pass_key);
      vTaskDelay(5000);
    return true;
  }
  bool onSecurityRequest(){
      ESP_LOGI(LOG_TAG, "SecurityRequest");
    return true;
  }

As for ISSUE#2, I will check how to use it, then try it afterwards...

void BLEServer::disconnect(uint16_t connId){
    esp_ble_gatts_close(m_gatts_if, connId);
}
chegewara commented 4 years ago

f the above is for ISSUE#1, are you advising that, if I change the return from true ➝ false in either or both of the snippets below, a failed authentication would lead to an automatic termination of the BLE connection?

I am assuming that peer device, smartphone, should get response it is not authenticated and maybe, but im not sure, low level esp-idf library will also register that device as non authenticated and wont let to read/write characteristics that require authorization.

d0natz commented 4 years ago

I understand now... If that would be the case, it would be the best option. I will test this idea, and let you know the results.

As always, thanks for your advice.

d0natz commented 4 years ago

About ISSUE#1, I tried toggling the return value : true ⇒ false in either or both of the onConfirmPin() and onSecurity() commands. Unfortunately, even if the onAunthenticationComplete() fails, results show that as long as the peer device stays connected, Characteristic read/write is still permitted between the ESP and peer device.

As always, thanks for your advice.

chegewara commented 4 years ago

https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEHIDDevice.cpp#L117 https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEHIDDevice.cpp#L135-L136

societyofrobots commented 4 years ago

Was Issue #1 resolved? I'm having the same problem and I've tried all the suggestions in this thread.

I enter the wrong password, but I can still connect with iOS, and also Android.

I am using the Android app 'Serial Bluetooth Terminal'. I click to connect within the app, and it asks to pair. I click 'cancel' so it doesn't pair, without ever entering the password. I then click connect again, and it's connected.

Ideas?