NimBLE-Arduino icon indicating copy to clipboard operation
NimBLE-Arduino copied to clipboard

onSecurityRequest() does not get called

Open christophhebeisen opened this issue 3 years ago • 2 comments

Version: NimBLE-Arduino @ 1.4.0

I want to use onSecurityRequest() to decide if a client is allowed to bond. However, it seems that the method is never called as opposed to onAuthenticationComplete(), which is called as expected.

The code below is based on the NimBLE_Secure_Server.ino example with the addition of security callbacks:

class SecurityCallbacks : public NimBLESecurityCallbacks {
  [...]
  bool onSecurityRequest(){
    bool ret=false;
    ESP_LOGI(logTag, "onSecurityRequest()");
    // logic to decide if to allow request
    return ret;
  }
  void onAuthenticationComplete(ble_gap_conn_desc* gcd){
    ESP_LOGI(logTag, "onAuthenticationComplete()");
  }
};

void setup() {
  [...]
  NimBLEDevice::setSecurityAuth(true, true, true);
  NimBLESecurityCallbacks *pSecurityCallbacks=new SecurityCallbacks();
  BLEDevice::setSecurityCallbacks(pSecurityCallbacks);
  NimBLEDevice::setSecurityPasskey(123456);
  NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
  [...]
}

Output generated by connecting and bonding my phone to the device is shown below.

D NimBLEServer: >> handleGapEvent: 
D NimBLEServerCallbacks: onConnect(): Default
D NimBLEServerCallbacks: onConnect(): Default
D NimBLEServer: >> handleGapEvent: 
D NimBLEServer: << handleGATTServerEvent
D NimBLEServer: >> handleGapEvent: 
D NimBLEServer: Connection parameters updated.
D NimBLEServer: >> handleGapEvent: 
D NimBLEServer: << handleGATTServerEvent
D NimBLEServer: >> handleGapEvent: 
D NimBLEServer: Connection parameters updated.
D NimBLEServer: >> handleGapEvent: 
D NimBLEServerCallbacks: onPassKeyRequest: default: 123456
D NimBLEServer: BLE_SM_IOACT_DISP; ble_sm_inject_io result: 0
D NimBLEServer: << handleGATTServerEvent
D NimBLEServer: >> handleGapEvent: 
[I][NimBLETest.ino:36] onAuthenticationComplete(): onAuthenticationComplete()
D NimBLEServer: >> handleGapEvent: 
D NimBLEServer: << handleGATTServerEvent
D NimBLECharacteristic: Characteristic 0x1235 Read event
D NimBLECharacteristicCallbacks: onRead: default
D NimBLECharacteristicCallbacks: onRead: default
D NimBLEServer: >> handleGapEvent: 
I NimBLEServer: subscribe event; attr_handle=8, subscribed: false

As far as I understand, onSecurityRequest() should have been called during bonding (and that is what happened in the original ESP32 BLE library).

christophhebeisen avatar Oct 16 '22 05:10 christophhebeisen

The NimBLE stack does not provide a callback for this unfortunately.

h2zero avatar Oct 16 '22 15:10 h2zero

Thank you for your response. I just realized that NimBLESecurityCallbacks is deprecated anyway in favour of using NimBLEServerCallbacks so I probably shouldn't have been using it in the first place. NimBLEServerCallbacks still has onConfirmPIN, which could be used to implement similar functionality. However, this method does not appear to get invoked either. This is a bit confusing since it is documented functionality - is that one not available either?

The reason why I am concerned about this is that once I call BLEDevice::setSecurityPasskey() the device will stay bondable forever (until a restart) - with the same pin. To prevent unauthorized bonding, I need a way to allow or deny bonding and I am at a loss for how to do this is these callbacks do not work - there doesn't seem to be a way to "unset" the passkey...

christophhebeisen avatar Oct 16 '22 23:10 christophhebeisen

Closing this as unable to reproduce, also will be changed in the near term.

h2zero avatar Jun 04 '24 21:06 h2zero