nimble: correct way to terminate connection when pairing key is incorrect
Posted: Sun Feb 25, 2024 4:50 pm
Hi,
I am writing a firmware based on the bleprh example code. My device has a display, which I will be using to show the passkey (BLE_SM_IOACT_DISP). Currently, if I type in the incorrect passkey on my phone, "ble_gap_security_initiate" still succeeds and I connect to the device, except it is not authenticated/bonded/encrypted. In this case, I can read/write nonencrypted services. I only want to connect if it is secure. What is the correct way to do this? Currently, I have some code in "BLE_GAP_EVENT_ENC_CHANGE" case to terminate the connection but this does not seem correct.
My "bleprph_gap_event" code:
Config:
Any help would very much so be appreciated. Thank you!
I am writing a firmware based on the bleprh example code. My device has a display, which I will be using to show the passkey (BLE_SM_IOACT_DISP). Currently, if I type in the incorrect passkey on my phone, "ble_gap_security_initiate" still succeeds and I connect to the device, except it is not authenticated/bonded/encrypted. In this case, I can read/write nonencrypted services. I only want to connect if it is secure. What is the correct way to do this? Currently, I have some code in "BLE_GAP_EVENT_ENC_CHANGE" case to terminate the connection but this does not seem correct.
My "bleprph_gap_event" code:
- case BLE_GAP_EVENT_CONNECT:
- MODLOG_DFLT(INFO, "connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", event->connect.status);
- if (event->connect.status == 0) {
- rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
- assert(rc == 0);
- bleprph_print_conn_desc(&desc);
- MODLOG_DFLT(INFO, "\n");
- rc = ble_gap_security_initiate(event->connect.conn_handle);
- if (rc != 0) {
- MODLOG_DFLT(INFO, "Security could not be initiated, rc = %d\n", rc);
- return ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
- } else {
- MODLOG_DFLT(INFO, "Connection secured\n");
- }
- } else {
- /* Connection failed; resume advertising. */
- bleprph_advertise();
- }
- /*.....*/
- case BLE_GAP_EVENT_ENC_CHANGE:
- /* Encryption has been enabled or disabled for this connection. */
- MODLOG_DFLT(INFO, "encryption change event; status=%d ", event->enc_change.status);
- rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
- assert(rc == 0);
- bleprph_print_conn_desc(&desc);
- MODLOG_DFLT(INFO, "\n");
- // XXX is this the correct way to do this??
- if(desc.sec_state.authenticated == 0 || desc.sec_state.encrypted == 0 || desc.sec_state.bonded == 0) {
- MODLOG_DFLT(INFO, "failed pairing, terminating connection\n");
- ble_store_util_delete_peer(&desc.peer_id_addr);
- return ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
- }
- /* Initialize the NimBLE host configuration. */
- ble_hs_cfg.reset_cb = bleprph_on_reset;
- ble_hs_cfg.sync_cb = bleprph_on_sync;
- ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
- ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
- ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY;
- ble_hs_cfg.sm_bonding = 1;
- /* Enable the appropriate bit masks to make sure the keys
- * that are needed are exchanged
- */
- ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
- ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC;
- ble_hs_cfg.sm_mitm = 1;
- ble_hs_cfg.sm_sc = 1;
- /* Stores the IRK */
- ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
- ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;