Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
d0natz opened this issue Aug 9, 2020 · 11 comments

Comments

@d0natz
Copy link

d0natz commented Aug 9, 2020

Hi people,

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

Currently, I am using the codes here: #793 (comment). Based on my test observations:

  • In an "ESP32 ⇔ Android" bluetooth test connection,

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

  • However, In an "ESP32 ⇔ iPhone" bluetooth test connection,

Even if a wrong password is intentionally keyed-in during bluetooth pairing, the initial bluetooth connection will continue and not be automatically 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
Copy link
Collaborator

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
Copy link
Author

d0natz commented Aug 10, 2020

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
Copy link
Collaborator

chegewara commented Aug 10, 2020

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
Copy link
Author

d0natz commented Aug 11, 2020

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
Copy link
Collaborator

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
Copy link
Author

d0natz commented Aug 12, 2020

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
Copy link
Collaborator

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
Copy link
Author

d0natz commented Aug 12, 2020

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
Copy link
Author

d0natz commented Aug 13, 2020

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.

@societyofrobots
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants