... | @@ -111,7 +111,7 @@ If an application can find out the device's own Bluetooth classic address and sh |
... | @@ -111,7 +111,7 @@ If an application can find out the device's own Bluetooth classic address and sh |
|
|
|
|
|
On Android versions 6 and later (API level 23), applications do not have access to the device's own Bluetooth classic address. There are workarounds for accessing the address up to Android 8 (API level 26).
|
|
On Android versions 6 and later (API level 23), applications do not have access to the device's own Bluetooth classic address. There are workarounds for accessing the address up to Android 8 (API level 26).
|
|
|
|
|
|
Beyond that point, an application receiving an RFCOMM connection can still access the address of the remote device, and can send this information back to the remote device (via the RFCOMM connection or out-of-band) to enable the remote device to learn its own address. The developers of Thali called this technique "bro mode" after the phrase "help a brother out".
|
|
Beyond that point, an application receiving an RFCOMM connection can still access the address of the remote device, and can send this information back to the remote device (via the RFCOMM connection or out-of-band) to enable the remote device to learn its own address. The developers of Thali who invented this technique called it "help a brother out" or "bro mode".
|
|
|
|
|
|
This does not allow a group of devices to bootstrap connectivity entirely without user interaction, as would have been possible on earlier API levels: at least one device must be made discoverable in order to receive the first RFCOMM connection. But this technique can be used to reduce the amount of user interaction needed.
|
|
This does not allow a group of devices to bootstrap connectivity entirely without user interaction, as would have been possible on earlier API levels: at least one device must be made discoverable in order to receive the first RFCOMM connection. But this technique can be used to reduce the amount of user interaction needed.
|
|
|
|
|
... | @@ -137,9 +137,9 @@ To mitigate this risk, BLE uses a cryptographic key called the Identity Resolvin |
... | @@ -137,9 +137,9 @@ To mitigate this risk, BLE uses a cryptographic key called the Identity Resolvin |
|
|
|
|
|
During our research we encountered an open vulnerability which is extremely relevant to the public mesh application development space. [CVE-2020-12856: A Silent Pairing Issue in Bluetooth-based Contact Tracing Apps](https://raw.githubusercontent.com/alwentiu/COVIDSafe-CVE-2020-12856/master/CVE-2020-12856-19-June-2020.pdf) by authors Alwen Tiu and Jim Mussared, released in May 2020, describes an attack which silently creates a pairing between the attacker's device and a victim device. This results in the attacker learning the victim's Identity Resolving Key. The attacker can use this key to translate the victim's temporary addresses back to the permanent address, thus enabling the attacker to track the victim's movements.
|
|
During our research we encountered an open vulnerability which is extremely relevant to the public mesh application development space. [CVE-2020-12856: A Silent Pairing Issue in Bluetooth-based Contact Tracing Apps](https://raw.githubusercontent.com/alwentiu/COVIDSafe-CVE-2020-12856/master/CVE-2020-12856-19-June-2020.pdf) by authors Alwen Tiu and Jim Mussared, released in May 2020, describes an attack which silently creates a pairing between the attacker's device and a victim device. This results in the attacker learning the victim's Identity Resolving Key. The attacker can use this key to translate the victim's temporary addresses back to the permanent address, thus enabling the attacker to track the victim's movements.
|
|
|
|
|
|
In most public mesh protocols, each device uses some sort of publicly-identifiable address at the mesh layer so that other devices in the network can route messages to it, so at first the attacker's ability to track the victim via a permanent address does not seem like a major security issue. However, this attack is particularly relevant even in the public mesh context, because it allows for the identification of users even after a user stops using the public mesh application.
|
|
In most public mesh protocols, each device uses some sort of publicly-identifiable address at the mesh layer so that other devices in the network can route messages to it, so at first the attacker's ability to track the victim via a permanent address does not seem like a major security issue. However, this attack is particularly relevant even in the public mesh context, because it allows for the tracking of users even after they stop using the public mesh application.
|
|
|
|
|
|
The attack also allows the attacker to exploit the silently created pairing to act as a trusted peripheral such as a Bluetooth keyboard, giving the attacker control over the victim's device.
|
|
The attacker can also exploit the silently created pairing to act as a trusted peripheral such as a Bluetooth keyboard, giving the attacker control over the victim's device.
|
|
|
|
|
|
##### Silent Pairing Fix
|
|
##### Silent Pairing Fix
|
|
|
|
|
... | @@ -152,7 +152,7 @@ The COVIDSafe files that implement this fix are: |
... | @@ -152,7 +152,7 @@ The COVIDSafe files that implement this fix are: |
|
* <https://github.com/AU-COVIDSafe/mobile-android/blob/master/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassPairingFix.kt>
|
|
* <https://github.com/AU-COVIDSafe/mobile-android/blob/master/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassPairingFix.kt>
|
|
* <https://github.com/AU-COVIDSafe/mobile-android/blob/master/app/src/main/java/au/gov/health/covidsafe/streetpass/IBluetoothGattInvocationHandler.java>
|
|
* <https://github.com/AU-COVIDSafe/mobile-android/blob/master/app/src/main/java/au/gov/health/covidsafe/streetpass/IBluetoothGattInvocationHandler.java>
|
|
|
|
|
|
Because we want to utilize the BLESSED library, we apply a similar patch to the underlying `BluetoothGatt` object that is wrapped in the `BluetoothPeripheral` class.
|
|
Because we want to use the BLESSED library, we apply a similar patch to the underlying `BluetoothGatt` object that is wrapped in BLESSED's `BluetoothPeripheral` class.
|
|
|
|
|
|
#### Android Permissions
|
|
#### Android Permissions
|
|
|
|
|
... | @@ -189,43 +189,62 @@ Depending on the API level, various permissions must be granted by the user. On |
... | @@ -189,43 +189,62 @@ Depending on the API level, various permissions must be granted by the user. On |
|
* Let app always run in the background
|
|
* Let app always run in the background
|
|
* Show notifications
|
|
* Show notifications
|
|
|
|
|
|
On API level 30 and earlier, access to some Bluetooth APIs requires location-related permissions, and access to these APIs while the app is in the background may result in a warning being shown about the app accessing the user's location. This creates a UX hurdle for future public mesh applications because it could cause users to believe their locations are being tracked.
|
|
On API levels 30 and earlier, access to some Bluetooth APIs requires location-related permissions, and access to these APIs while the app is in the background may result in a warning being shown about the app accessing the user's location. This creates a UX hurdle for future public mesh applications because it could cause users to believe their locations are being tracked.
|
|
|
|
|
|
### BLESSED
|
|
### BLESSED
|
|
|
|
|
|
We have found that the open source Bluetooth library [BLESSED](https://github.com/weliem/blessed-android) is useful for working with BLE on Android. The project's README.md offers an introduction to the library for new users, and they also offer a number of [example projects](https://github.com/weliem/blessed-android/tree/master/app/src/main/java/com/welie/blessedexample) to help developers get started with BLESSED.
|
|
We have found that the open source Bluetooth library [BLESSED](https://github.com/weliem/blessed-android) is useful for working with BLE on Android. The project's README.md offers an introduction to the library for new users, and they also offer a number of [example projects](https://github.com/weliem/blessed-android/tree/master/app/src/main/java/com/welie/blessedexample) to help developers get started with BLESSED.
|
|
|
|
|
|
#### Peer Advertisement
|
|
#### Peer Advertisement
|
|
|
|
|
|
Peer advertisement happens using BLE's peripheral advertisement protocol. Peripheral devices build a schema of characteristics, and advertise their core service UUID over the Bluetooth frequency band.
|
|
Peer advertisement happens using BLE's advertisement protocol, which allows a peripheral device to send small advertisement packets periodically.
|
|
Using BLESSED's library, and their `PeripheralManager` class, you can easily create and add characteristics:
|
|
|
|
|
|
|
|
BluetoothGattCharacteristic allocatorChar = new BluetoothGattCharacteristic(ALLOCATOR_UUID,PROPERTY_READ, PERMISSION_READ);
|
|
* <https://j2abro.blogspot.com/2014/06/understanding-bluetooth-advertising.html>
|
|
gattService.addCharacteristic(allocatorChar);
|
|
* <https://source.android.com/docs/core/connect/bluetooth/ble_advertising>
|
|
peripheralManager.add(gattService);
|
|
|
|
|
|
|
|
And start advertising the GATT service:
|
|
Some devices (eg Huawei P8 Lite 2015) don't support advertising. Others (eg Moto G 4G) appear to support it, but aren't discovered by other devices.
|
|
|
|
|
|
peripheralManager.startAdvertising(adSettings, adData, scanResponse);
|
|
Advertising continues in the background until stopped by the application. If advertising is started while the app is in the foreground then it can continue in the background without needing background location permission (on Android versions that require location permissions for Bluetooth operations). Advertisements seem to be sent less frequently when the app is in the background and the screen is turned off.
|
|
|
|
|
|
For more information on how the `blessed` branch creates and advertises it's GATT service:
|
|
A BLE advertisement may be "connectable" or "scannable" (or neither). Connectable means that a device receiving the advertisement can connect to the device that sent it. Scannable means that a device receiving the advertisement can request additional data - the "scan record" - from the device that sent the advertisement. However, we found that some devices (eg Samsung J5 2016) receive the advertisement packet but not the scan record, so any information we make available via scan records also needs to be made available by other means.
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L261>
|
|
A connectable or scannable advertisement can include up to 31 bytes of data. To save energy, it's useful to include a UUID to identify the service being advertised. This allows devices listening for advertisements to filter out irrelevant advertisements without waking the CPU, as filtering can be done by the Bluetooth chipset. Self-assigned service UUIDs are 128 bits long, so including a service UUID in the advertisement uses 18 of the 31 available bytes (vendors who obtain UUIDs from the Bluetooth standards body can use shorter representations).
|
|
|
|
|
|
|
|
As a hack, an application can borrow one of the 16-bit manufacturer UUIDs (see the [assigned numbers spec](https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf)) to identify its advertisements in a more compact way, although with a risk of false positive matches.
|
|
|
|
|
|
|
|
The `blessed-gatt` branch uses connectable advertisements containing a 128-bit service UUID and a 32-bit PSM value for L2CAP CoC connections.
|
|
|
|
|
|
#### Peer Discovery
|
|
#### Peer Discovery
|
|
|
|
|
|
Scanning for nearby peers is a key component of the Bluetooth Low Energy protocol. When the Bluetooth service is running, the central component of the public mesh BLE service will scan in the background looking for peripherals that are advertising the set UUID for this application. When the service discovers a nearby peripheral using the BLESSED library, it will fire the `onDiscoveredPeripheral()` callback function. BLESSED will also automatically handle "service discovery" which is a handshake that happens behind the scene between the devices so the central device can understand what resources are being hosted by the peripheral. BLESSED conveniently also gives you a callback on this event called `onServicesDiscovered()`.
|
|
Scanning for nearby peers is a key component of the Bluetooth Low Energy protocol. When the Bluetooth service is running, the central component of the public mesh BLE service will scan in the background looking for peripherals that are advertising the service UUID for this application. When the service discovers a nearby peripheral via the BLESSED library, it will fire the `onDiscoveredPeripheral()` callback function. BLESSED will also automatically handle "service discovery", which is a handshake that happens behind the scenes between the devices so the central device can understand what resources are being hosted by the peripheral. BLESSED conveniently also gives you a callback on this event called `onServicesDiscovered()`.
|
|
|
|
|
|
#### Peer Connectivity
|
|
#### Peer Connectivity
|
|
|
|
|
|
Bluetooth Low Energy offers two different ways of actually connecting and sharing data between devices, the previously mentioned GATT service can be used to broadcast resources that centrals can connect, and read and write to. BLE also offers L2CAP, or "logical link control and adaptation protocol". L2CAP offers a "connection oriented channel" approach that is much closer to traditional socket programming than the GATT protocol. This makes programming larger data transfers with L2CAP much easier, however API support for L2CAP on android devices is worse compared to GATT, so our general thinking is to attempt to create links between devices using L2CAP, but fall back to using GATT in case devices in the handshake do not support L2CAP.
|
|
As previously mentioned, Bluetooth Low Energy offers two different ways of actually connecting and sharing data between devices: GATT and L2CAP CoC. L2CAP CoC is much closer to traditional socket programming than the GATT protocol. This makes programming larger data transfers with L2CAP much easier, however API support for L2CAP on Android devices is worse compared to GATT, so our general thinking is to attempt to create links between devices using L2CAP, but fall back to using GATT in case the devices do not support L2CAP.
|
|
|
|
|
|
##### GATT
|
|
##### GATT
|
|
|
|
|
|
Like most other BLE functionalities, BLESSED allows us to easily connect to a given `BluetoothPeripheral` object by using the `centralManager.connectPeripheral()` method. For the full implementation of peer connections on the `blessed` branch: <https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L320>
|
|
Using BLESSED's `PeripheralManager` class, you can easily create and add characteristics:
|
|
|
|
|
|
##### L2CAP
|
|
BluetoothGattCharacteristic allocatorChar = new BluetoothGattCharacteristic(ALLOCATOR_UUID, PROPERTY_READ, PERMISSION_READ);
|
|
|
|
gattService.addCharacteristic(allocatorChar);
|
|
|
|
peripheralManager.add(gattService);
|
|
|
|
|
|
With L2CAP, there is less of a divide between "central" and "peripheral" devices like in the GATT system. Instead of advertising a set of resources like a GATT peripheral device, with L2CAP, devices advertise a "PSM" value which is similar to a port number, and open a Bluetooth Server Socket running on that PSM value. On our `blessed` branch, we advertise the open socket if the device supports L2CAP:
|
|
And start advertising the GATT service:
|
|
|
|
|
|
|
|
peripheralManager.startAdvertising(adSettings, adData, scanResponse);
|
|
|
|
|
|
|
|
See this file for more information on how the `blessed-gatt` branch creates and advertises its GATT service:
|
|
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L261>
|
|
|
|
|
|
|
|
When a central device discovers a peripheral that's advertising the app's service UUID, it connects to the `BluetoothPeripheral` object by using the `centralManager.connectPeripheral()` method. See the following file for the full implementation of peer connections on the `blessed-gatt` branch:
|
|
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L320>
|
|
|
|
|
|
|
|
##### L2CAP CoC
|
|
|
|
|
|
|
|
With L2CAP CoC, there is less of a conceptual divide between "central" and "peripheral" devices than there is with GATT. Instead of advertising a set of services consisting of characteristics, a peripheral using L2CAP CoC can just advertise a "PSM" value, which is similar to a port number, and open a Bluetooth server socket running on that PSM value. On our `blessed` branch, we advertise the PSM if the device supports L2CAP CoC:
|
|
|
|
|
|
```Java
|
|
```Java
|
|
if (USE_L2CAP && SDK_INT >= 29 && serverSocket == null) openServerSocket();
|
|
if (USE_L2CAP && SDK_INT >= 29 && serverSocket == null) openServerSocket();
|
... | @@ -243,7 +262,9 @@ if (USE_L2CAP && SDK_INT >= 29) { |
... | @@ -243,7 +262,9 @@ if (USE_L2CAP && SDK_INT >= 29) { |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
Then, whenever we discover a L2CAP-compatible device, we can connect to it using a method like the `connectViaSocket()` method on the `blessed` branch: <https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L416>
|
|
Then, whenever we discover an L2CAP-compatible device, we can connect to it using a method like the `connectViaSocket()` method on the `blessed` branch:
|
|
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L416>
|
|
|
|
|
|
#### Notes
|
|
#### Notes
|
|
|
|
|
... | @@ -484,7 +505,7 @@ https://www.wi-fi.org/product-finder-results?sort_by=certified&sort_order=desc&c |
... | @@ -484,7 +505,7 @@ https://www.wi-fi.org/product-finder-results?sort_by=certified&sort_order=desc&c |
|
|
|
|
|
### Companion Device Pairing
|
|
### Companion Device Pairing
|
|
|
|
|
|
Android versions 8 and later (API level 26) provide a high-level API for discovering nearby Bluetooth and Wi-Fi devices without the application needing to hold the various permissions that are required for using the Bluetooth and Wi-Fi APIs directly.
|
|
Android versions 8 and later (API level 26) provides a high-level API for discovering nearby Bluetooth and Wi-Fi devices without the application needing to hold the various permissions that are required for using the Bluetooth and Wi-Fi APIs directly.
|
|
|
|
|
|
https://developer.android.com/guide/topics/connectivity/companion-device-pairing
|
|
https://developer.android.com/guide/topics/connectivity/companion-device-pairing
|
|
|
|
|
... | | ... | |