This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Pairing passkey , cancel pairing on android side still give access to characteristic

Hi ,

I'm working on nrf52833, s113. 

I have trouble to secure my system. It has no kayboard or screen, and with 6digit fixd pathkey( no other choice).

That's mean it advertise once wake up with accelerometre. 

I want to protect access to my 4 characteristics. So i enable bounding and  MITM. to have the passkey popup on android. Without MITM, i don't have passkey pop up. But then the strange stuff appar:

My program is based on hrs example + dfu merging.

I was thinking that, by using pairing protection with 6 digit fixed pathkey( no other choice cause no IO), i would not be able to read/write my characteriqtics. But with nrfConnect, if you are fast enough, when bounding window pops up , and you click cancel and really fast after, you are able to click on the row to read a characteristics, the connexion is maintained and you have access to all , without been securly paired !!! Note that here, my charac are in OPEN. I juste relly on the fact that the passkey will avoid to go next step...

I know i can protect each caracteristic by using : BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM , what i did. 

But a side effect appears: after first pairing on the phone by writing the 6 digit passkey, the same windows pops up FOR EACH characteristic you read ( only the first time) ... so it s a bit anoying because you have the feeling to have paired at connexion step , but in fact it has absolutely no impact on security.

If you click cancel you are still connected and if fast enough you can even have access to all. If you paired successfully, you will have to enter this same path key for each characteristic you have protected, what give a strange effect to the final user, he has the feeling that first pairing didn't worked.

What i need is :First, ask pairng after connect. If yes 6digit ok , no more asked user to enter pathkey. If no or cancel, close connexion or retry but doesn't give access. Only paired device should have access.

Hope to have been clear :)

Parents
  • Here is my console trace when i click on cancel and wait ( no fast click on characteristic):

    <info> app: ADVERTISING ! Wait connexion or TIMEOUT...
    <debug> nrf_sdh_ble: BLE event: 0x10.
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <info> app: CONNECTED
    
    <debug> nrf_sdh_ble: BLE event: 0x3A.
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <debug> nrf_sdh_ble: BLE event: 0x12.
    
    <info> app: 	  BLE_GAP_EVT_CONN_PARAM_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x23.
    <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 251 bytes.
    <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
    <info> app: 	  BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST	
    <debug> nrf_sdh_ble: BLE event: 0x24.
    <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 27
    <debug> nrf_ble_gatt: max_tx_octets: 27
    <debug> nrf_ble_gatt: max_rx_time: 2120
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <info> app: 	  BLE_GAP_EVT_CONN_PARAM_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x19.
    <info> app: 	  BLE_GAP_EVT_AUTH_STATUS	
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <info> app: 	  BLE_GAP_EVT_CONN_PARAM_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x11.
    <info> app: DISCONNECTED
    
    <info> app: try to advertise...
    <info> app: ADVERTISING ! Wait connexion or TIMEOUT...

    Here the trace if i do nothing when pop up 6 digit happens:

    <info> app: try to advertise...
    <info> app: ADVERTISING ! Wait connexion or TIMEOUT...
    <debug> nrf_sdh_ble: BLE event: 0x10.
    <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update, no change
    <debug> nrf_ble_gatt: Requesting to update ATT MTU to 247 bytes on connection 0x0.
    <info> app: CONNECTED
    
    <debug> nrf_sdh_ble: BLE event: 0x3A.
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <info> app: 	  BLE_GAP_EVT_CONN_PARAM_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x23.
    <debug> nrf_ble_gatt: Peer on connection 0x0 requested a data length of 251 bytes.
    <debug> nrf_ble_gatt: Updating data length to 27 on connection 0x0.
    <info> app: 	  BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST	
    <debug> nrf_sdh_ble: BLE event: 0x24.
    <debug> nrf_ble_gatt: Data length updated to 27 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 27
    <debug> nrf_ble_gatt: max_tx_octets: 27
    <debug> nrf_ble_gatt: max_rx_time: 2120
    <debug> nrf_ble_gatt: max_tx_time: 2120
    <info> app: 	  BLE_GAP_EVT_DATA_LENGTH_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <info> app: 	  BLE_GAP_EVT_CONN_PARAM_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x12.
    <info> app: 	  BLE_GAP_EVT_CONN_PARAM_UPDATE	
    <debug> nrf_sdh_ble: BLE event: 0x19.
    <info> app: 	  BLE_GAP_EVT_AUTH_STATUS	
    <debug> nrf_sdh_ble: BLE event: 0x11.
    <info> app: DISCONNECTED
    <info> app: try to advertise...
    <info> app: ADVERTISING ! Wait connexion or TIMEOUT...
    <debug> nrf_sdh_ble: BLE event: 0x26.
    <debug> app: ADVERTISING TIMEOUT, ADV_SET_TERMINATED :(
    <info> app: ACCEL IN LOW POWER
    

  • So i have tested with BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM . I still have cancel pairing no impact effect. But i don't have pop up windows for each char. Because i think in flash this phone is memorized .

    So i did a test, I erase all my flash. Programm debug bootloader, settings page, Softdevice s113 and run the fw. Scan on android, connect. First, no pop up to enter 6 digit appears. I see all my char. When i try to read, the pop up 6 digit ask for the passkey. If i enter it , i can read the char and three other too.

    Now i diconnect and unbound on android side. Re connect. And here pop up window appear ! It was not the case at the first trial, idon't know why. May be because now , it is bounded in my flash, so it ask after connexion . I don't enter the code, and it runs for a while, keeping the connexion but doing nothing on android side ( just a circular row running in loop telling me it is waiting for something indefinitively).

    So i disconnect. I re connect, it ask for the paskey, i enter it successfully . I can read my char without re entering passkey.

    If i disconnect, and reconnect, now it is succesfully bounded, so no more pop and everything is fine.

    Conclusion, there is something not robust at pairing phase when nobody knows each others, and i click cancel.

  • That was the point !!!

    Thanks, now if i click Cancel when pop up arrive, it disconnects the link and i also add all the print for pm_event. When i click cancel i can see PM_EVT_CONN_SEC_FAILED happen and then cnnexion is forced close by nrf52833 so that's good !

    I have still few thing that is not perfect:

    1. When chip is erased, blank, no bounded device in memory. Android not bounded anymore too. All systeme freshly new. I can connect and see the list of char. Because i protected it, i can't read without pairing by 6 digit code. But is there a way to pop up 6 digit windows after connexion and not only when i try to read a characteristic ?

    2.I f i unbound from Android side, for sur, it stay bounded in my nrf52 memory. How many bounded device can we add in memory before to be full ?

    3. Sould I prepare a way to clean bounded device to avoid being out of memory ? I have a settings char, can i use it for calling a cleaning bounded device function for example or is there a better native way to do it please ?

    4. If i do the contrarie, keep bounded in android nrf App, but clear my uC. I try to connect, and this error happen:

    <info> app: 	 PM_EVT_CONN_SEC_START                 	
    <info> peer_manager_handler: Connection security failed: role: Peripheral, conn_handle: 0x0, procedure: Encryption, error: 4102
    <warning> peer_manager_handler: Disconnecting conn_handle 0.
    <info> app: 	 PM_EVT_CONN_SEC_FAILED                	
    <info> app: 	  BLE_GAP_EVT_SEC_INFO_REQUEST	
    <debug> nrf_sdh_ble: BLE event: 0x11.
    <info> app: DISCONNECTED

    pop up windows doesn't appear, so i have to unbound in Android and start a fresh new pairing process.

    thanks a lot for your help, at least i progress Slight smile

  • Hi Florian,

    Olfox said:
    But is there a way to pop up 6 digit windows after connexion and not only when i try to read a characteristic ?

    You need to add pm_handler_secure_on_connection to ble_evt_handler function to handle the connection? The function is for securing a connection when it is established. You can refer to ble_app_gls on how to use it.  

    Olfox said:
    How many bounded device can we add in memory before to be full ?

     See this answer.  

    Olfox said:
    3. Sould I prepare a way to clean bounded device to avoid being out of memory ?

    You can use pm_peers_delete() which is a function deleting all data stored for all peers. As for the disconnections, you do this however you like, for example by calling a sd_ble_gap_disconnect event. You can refer to ble_app_gls on how to use it.  

     

    Olfox said:
    4. If i do the contrarie, keep bounded in android nrf App, but clear my uC. I try to connect, and this error happen:

     The error is as expected because the device lost the bond information. You have to delete bond info on the phone. 

    -Amanda H.

  • Thanks Amanda,

    I have another issue, when i connect and disconnect very fast , nrf52 connect, start running timer etc .. but doesn't detect the disconnexion. So my system run and consume while nobody is no more connected. The bad thing is that, there is no prossibility at the moment to detect it.

    Is there a way to detect a disconnexion even if the BLE _EVT_DISCONNECT has not been set ? I was thinking to use a timer that i reload after each charceteristic reading, and if it times out i force a disconnexion. 

    I have seen a timer existing in gls example : PM_HANDLER_SEC_DELAY_MS

    But it seems to not manage this deconnexion missing detection

  • I think the only way to find the cause we need an on-air sniffer log. I suspect the case here may be that the phone is actually still in a connection here, or at least the phone think it is in a connection since it may be waiting for an ack on the previous terminate link packet. If the ack is lost, then the phone will need to wait for a supervisor timeout before the next link can be established. The peer device will only send one ack when receiving the terminate link packet before disconnect, this is according to BLE spec.

    -Amanda H.

  • Yes , i was able to reproduce the problem( it is quiet easy unfortunatly ...) and here is the log. We see that there is no packet exchange anymore once i break the link by exiting my screen on my app. 

    #define NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION 65535

    what should happen after 65353 ms ( almost 11 minutes?), because i let it run in this bad deconnexion states and nothing happens.

    thank you !

    links keep connected on uC but not in android connect lign20866.pcapng

    I can also see in my nrf console after breaking the link this :BLE_GAP_EVT_CONN_PARAM_UPDATE occurs. one time.

Reply Children
  • Hi Florian, 

    As I know from other cases, if you connect and disconnect very fast, the app might not send out the disconnection command as expected. From your sniffer log, the phone is actually still in a connection. If the app sends a disconnection command, you should see the opcode in the log as

      

    -Amanda H.

  • Hm so it is "normal" . But impossible to let the system running this way, batterie will die very fast, so i need a mecanism to detect if nobody is really connected, else i'm stuck in this state for ever...

    SO i see two posibilities:

    A.

    - use a read autorization on characteristic that should generate BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event in ble_on_ble_evt function, for each trial of reading. I will clear a timeout timer in this event. If timeout timer occurs, i force disconnection.

    2 questions here:

    1. How to "reload" the timer dynamically when it is running. I see no API funciton to do this and i meet a lot of trouble with stop , change et start timer function when it is already running. As it count from 0 to x , should i just clear a register ot a variable ?

    2. Should i call  in BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST  event ? According tho this schematics, i have to give authorize by answering to Soft Device that it can give access to peer.

    B.

    Rely on the NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION that, if i understood should expire after a certain time of inactivity, what is not the case in my application it is set to 65535 so around 11minutes but it never generate any ble event or force disconnect. Do i understand correctly its purpose ? Is there some code to add to manage it ?

    Thanks a lot !

  • Hi Florian, 

    Olfox said:
    Hm so it is "normal" .

    That is not normal. It is a known issue on our app. 

    Olfox said:

    A.

    - use a read autorization on characteristic that should generate BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event in ble_on_ble_evt function, for each trial of reading. I will clear a timeout timer in this event. If timeout timer occurs, i force disconnection.

    I think it's a good solution. You could add a timeout in your application to check if you get some activity specific to the app you are using (read or writes to a specific characteristic etc). See my colleague Susheel's answer in this post for the timeout implement. 

    Olfox said:

    B.

    Rely on the NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION that, if i understood should expire after a certain time of inactivity, what is not the case in my application it is set to 65535 so around 11minutes but it never generate any ble event or force disconnect. Do i understand correctly its purpose ? Is there some code to add to manage it ?

     All BLE connections have a supervision timeout. If there are no packets within the supervision timeout, the connection will end with the disconnect reason being "timeout". However, the BLE connection will not end, as long as the BLE stack on the phone still works. From your log, the master (phone) still sent the ack. Therefore, it would not disconnect after a supervision timeout.

     -Amanda H. 

  • Ok issue of fast connect /disconnect happens with your app, but also with mine, so may be it is linked to Android ?

    I have implemented the reste to check for disconnexion and it works fine :).

    We are very busy now with pairing in our app. Do you know if NrfConnect i sable to get from IOs and Android the list of paired devices ?

    Because we scan and try to connect to a list of paired succesfully devices saved into our app when we launch it. But imagine user has unpaired with android menu. we try to connect something unpaired. So in running mode , the pop up pairing keys happens to enter 6 digit. But It is on top of our app and we have no way to give the good code to enter to the user...

Related