hbldh / bleak

A cross platform Bluetooth Low Energy Client for Python using asyncio
MIT License
1.63k stars 282 forks source link

pairing with encryption, no MITM protection / Just Works #373

Open ChrisHoS opened 3 years ago

ChrisHoS commented 3 years ago

Description

Wanted to pair to a slave with encryption level 2 / Just Works / LE Security Mode 1, Level 2

What I Did

  1. set up the server with Nordic nRF Connect and nRF52840 Dongle nRF_Connect_Server_with_encrypted_characteristic

  2. connected, tried to pair to slave

Comment:

I apologize for not providing a non-vendor specific example.

import asyncio
import uuid
import logging
from  bleak import BleakClient, discover

DATA_RX_CHARACTERISTIC_UUID = "EF680903-9B354-9339-B105-2FFA9740042"
address = "E8:40:C6:EF:5F:C7"

async def scan():
    devices = await discover()
    for d in devices:
        print(f"{d.name}: {d.address}: {d.rssi}dB")

async def run_ble(address):
    async with BleakClient(address) as client:
        await client.is_connected()
        await client.pair(protection_level=2)
        # hello world = 0x68 0x65 0x6c 0x6c 0x6f 0x20 0x77 0x6f 0x72 0x6c 0x64
        await client.write_gatt_char(uuid.UUID(DATA_RX_CHARACTERISTIC_UUID), str.encode("hello world"))

def run():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(scan())
    loop.run_until_complete(run_ble(address))

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)
    run()

DEBUG:bleak.backends.dotnet.scanner:Received E8:40:C6:EF:5F:C7: nRF Connect.
DEBUG:bleak.backends.dotnet.scanner:Received E8:40:C6:EF:5F:C7: Unknown.
DEBUG:bleak.backends.dotnet.client:Connecting to BLE device @ E8:40:C6:EF:5F:C7
DEBUG:bleak.backends.dotnet.client:_ConnectionStatusChanged_Handler: 1
DEBUG:bleak.backends.dotnet.client:Get Services...
INFO:bleak.backends.dotnet.client:Services resolved for BleakClientDotNet (E8:40:C6:EF:5F:C7)
DEBUG:bleak.backends.dotnet.client:Disconnecting from BLE device...
DEBUG:bleak.backends.dotnet.client:_ConnectionStatusChanged_Handler: 0
Traceback (most recent call last):
  File "C:/git/fire/asd/test_nrf52_dongle_server_with_bleak_client/src/bleak_client.py", line 32, in <module>
    run()
  File "C:/git/fire/asd/test_nrf52_dongle_server_with_bleak_client/src/bleak_client.py", line 27, in run
    loop.run_until_complete(run_ble(address))
  File "C:\Users\honeggec\AppData\Local\Programs\Python\Python37\lib\asyncio\base_events.py", line 587, in run_until_complete
    return future.result()
  File "C:/git/fire/asd/test_nrf52_dongle_server_with_bleak_client/src/bleak_client.py", line 19, in run_ble
    await client.pair(protection_level=2)
  File "C:\git\fire\asd\test_nrf52_dongle_server_with_bleak_client\.env\lib\site-packages\bleak\backends\dotnet\client.py", line 331, in pair
    "Cannot set minimally required protection level yet..."
NotImplementedError: Cannot set minimally required protection level yet...
hbldh commented 3 years ago

Maybe that would do the trick. I was content with the protection_level=1 as a start on Windows. It is not good enough, but it points the way for future expasion at least. I also had no device to test it with...

You are free to try to get it to work, since I will not have time and energy to do it for quite some time I am afraid.

patrick-dojofive commented 10 months ago

Is the winnt backend restricted to protection_level 1 still?

EugeneNdungu commented 1 week ago

i'd like to follow up on @patrick-dojofive question. I am attempting to pair with protection_level 2 but the logs I get indicate that the protection level used to pair is protection_level 1(i might also just be doing something wrong). I am working with:

Here are the logs that I was able to collect( i apologize if the logs provided are not sufficient, it is what I was able to get for now but I am working on getting more logs)

2024-06-24 14:41:14 - DEBUG - bleak.backends.winrt.client :: Connecting to BLE device @ CD:5D:68:45:A0:5F
2024-06-24 14:41:14 - DEBUG - bleak.backends.winrt.client :: getting services (service_cache_mode=None, cache_mode=None)...
2024-06-24 14:41:15 - DEBUG - bleak.backends.winrt.client :: max_pdu_size_changed_handler: 251
2024-06-24 14:41:15 - DEBUG - bleak.backends.winrt.client :: session_status_changed_event_handler: id: BluetoothLE#BluetoothLE48:89:e7:29:1c:f5-cd:5d:68:45:a0:5f, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.ACTIVE: 1>
2024-06-24 14:41:15 - DEBUG - bleak.backends.winrt.client :: CD:5D:68:45:A0:5F: services changed
2024-06-24 14:41:16 - DEBUG - bleak.backends.winrt.client :: CD:5D:68:45:A0:5F: services changed
2024-06-24 14:41:17 - INFO - bluetooth_controller :: Connected: True
2024-06-24 14:41:17 - DEBUG - bluetooth_controller :: 123456
2024-06-24 14:41:19 - INFO - bleak.backends.winrt.client :: device id: 'BluetoothLE#BluetoothLE48:89:e7:29:1c:f5-cd:5d:68:45:a0:5f'
2024-06-24 14:41:19 - INFO - bleak.backends.winrt.client :: protection level: <DevicePairingProtectionLevel.ENCRYPTION: 2>
2024-06-24 14:41:20 - DEBUG - bleak.backends.winrt.client :: session_status_changed_event_handler: id: BluetoothLE#BluetoothLE48:89:e7:29:1c:f5-cd:5d:68:45:a0:5f, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.CLOSED: 0>
2024-06-24 14:41:20 - DEBUG - bleak.backends.winrt.client :: max_pdu_size_changed_handler: 23
2024-06-24 14:41:20 - DEBUG - bleak.backends.winrt.client :: closing requester
2024-06-24 14:41:20 - DEBUG - bleak.backends.winrt.client :: closing session
2024-06-24 14:41:20 - INFO - bleak.backends.winrt.client :: Pairing result: 0, Protection level used: 1
2024-06-24 14:41:20 - INFO - bleak.backends.winrt.client :: Paired to device with protection level <DevicePairingProtectionLevel.NONE: 1>.
EugeneNdungu commented 1 week ago

After collecting some more logs, I identified that the issue was most likely due to a mismatch between the client's pairing request and the server's pairing response. Below are some key observations:

Client's(PC) Pairing Request:

Server's Pairing Response:

We are looking into how the server firmware can be configured to match the client's pairing request requirements.

As it is right now though, is there a way that one can use bleak to match the client's pairing requirements with those of the server as provided above?