How to prevent unauthorized users from connecting to Arduino BLE device? - ios

I was looking at this BLE demo for Arduino:
https://github.com/dzindra/BLE-iOS-demo/blob/master/esp32blinky/esp32blinky.ino
I noticed that there is no "Authentication / Authorization" or explicit "Connection code".
The code consists of creating services and characteristics, and advertising them. At best you can see the following callbacks which are triggered when a client connects:
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("Connected");
};
void onDisconnect(BLEServer* pServer) {
Serial.println("Disconnected");
}
};
I was wondering what approach people follow for ensuring that users can connect to an Arduino's BLE only if they are the owner (for example, pressing a button to "trigger" connection mode) etc...
On deeper searching I found :
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/Arduino/security/BLE_server/BLE_server_passkey/BLE_server_passkey.ino
This other example shows how an ESP32 acting as a client would authenticate into a server:
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLETests/Arduino/security/BLE_client/BLE_client_passkey/BLE_client_passkey.ino
Both seem to be good examples for how two ESP32's could act as a client / server and authenticate each other. But then how would I get my iPhone to authenticate ? I use the following iPhone example for simply connecting without authentication.
Things seem a bit "hacky", and was wondering if there is an authoritative answer on how to connect to an Arduino BLE with authentication ?
EDIT: Basically, I wan't to prevent random people from just connecting to my BLE Device. I do not need anything more than that (I don't need encryption). I just want to prevent random people from connecting to my device, and breaking my smartphones connection with my BLE Device.

It seems no matter what mechanism you use to verify a valid connection the problem remains that if your BLE device is actually using advertising packets to deliver data, then when someone trys to connect, until you disconnect an unauthorised connection the advertising packet transmission is interrupted.
I use a small window of opportunity to write a correct value to a register otherwise resetting the connection.

Related

Pair and Connecting to Bluetooth Classic Speaker iOS

I realise most of the searches are quite old on this topic and not after Core Bluetooth now supports more than just BLE connections (https://developer.apple.com/videos/play/wwdc2019/901?time=556).
Simply by running the RxBluetoothKit example app I am able to discover my speaker and inspect its services. However I am unsure how to actually get the speaker to pair with the phone, after a while the speaker disconnects. I am struggling to get information on the protocol and/or how to proceed.
Or is this still not possible: "And so if you're calling connect on a BR/EDR device, if your app is in foreground, then we'll try to make a connection out to that device for you." - it seems like querying and communication with an already paired device is what they were getting at in the talk.
Thanks in advance.

If a BLE can't force a disconnect, how can we authenticate a connection?

I believe I read that the peripheral side cannot terminate a connection?
terminate a connection CBPeripheralManager side
How then, can we authenticate a connection at the application level? We are making an iOS app connect to another iOS app, we only want them to connect to each other. After connection they exchange private-key-based challenge/response questions, and a failure should result in a refusal of the connection. This of course works fine on the central side, if it doesn't get the correct reply it closes the connection. But if the peripheral cant cancel the connection, then how do we prevent a different central from connecting, and staying connected to the peripheral?
When a central connects but does not authenticate correctly, do not respond to requests from it. Every CBATTRequest includes the requesting central, and updateValue(_for:onSubscribedCentrals:) lets you control which centrals you respond to.
If they're not authenticated. Don't talk to them. Or more correctly, send them .insufficientAuthentication to all their requests. If they are well behaved, they will disconnect. If they are badly behaved, there is nothing you can do about that (this is always true; even if you could disconnect them, they could still flood you with connection requests).
You cannot force them to disconnect, however. They may be communicating with another app, and you are not allowed to stop that. You can only refuse to talk to them yourself or send them errors.

Failure to reconnect after De-authentication from Cisco AP Wifi

Apologizing in advance, I am no 802.11 expert and this is a long winded question...
I am working on an iOS voip client, we use the Cocoaasyncsocket library for our TCP/UDP connections. The app/iDevice is allowed to roam in/out of wifi coverage (for the purposes of this discussion we will assume the app is using wifi only... no cellular connection). We have the appropriate plist settings for backgroundmode (voip, audio) as well as requiring persistent wifi.
We are having a problem that seems particular to Cisco AP's. With the client app in the foreground and roaming out and in of wifi range, we noticed that eventually the iOS device will eventually not automatically rejoin the network. After a great deal of debug the failure to rejoin was noted to have nothing to do with the app. The failure to re-join can ultimately be reproduced by forcing the AP (via config) to deauthenticate the iDevice three times. After the 1st and 2nd deauthentications, the iDevice readily automatically re-joins. But after the 3rd time, iOS does not automatically rejoin the network.
The network will be rejoined if, for example, the iOS email app is put in the foreground.
We were curious if any other VOIP type apps suffered this problem, and ran an experiment with running FaceTime and Skype on the iOS device.
Skype behaved much like our voip app, after the 3rd deauth the connection was lost. Trying to initiate another call resulted in a message to the effect of "must have an internet connection to make a call".
FaceTime did disconnect on the 3rd deauth and failed to automatically rejoin... however, we were able to re-initiate another FaceTime call which caused iOS to rejoin the network and make the call.
We would like to emulate the FaceTime behavior, but so far do not understand what we should be doing differently. To the best of our knowledge, we are properly closing the open sockets when we get disconnected. Is anyone familiar with this issue and have some insight to offer?

iOS Core Bluetooth BLE Security with Hm10 Peripherial

Can someone suggest if it is possible in BLE communication to authenticate the central from peripherial before connection is established?
Example:
1) Peripherial Advertises continuously
2) Central discovers Peripherial and sends connection request
3) Connection is Established and Advertising stops
3) Peripherial authenticates central via AES or Pairing etc.
4) If authentication is succesful transfer data.
Either ways once this malicious central has connected to peripherial the Genuine Central will not be able to as each peripherial. If I have understood properly, Peripherial can not end connection or start connection and peripherial do not allow simultaneous connections.
How can I solve this problem? Even if some way of terminating connection from peripherial is made possible, the malicious central will keep reconnecting hence essentially performing DENIAL OF SERVICE(DOS) attack.
Thank You!
You have the sequence slightly wrong. It should be -
Peripheral advertises
Central discovers peripheral and attempts to connect
PIN is requested if central is not already paired
Connection completes if pairing is successful. If not return to state 1
If connection is successful advertising stops and data can be transferred.
So, the security is based on the PIN being kept a secret. If the PIN is well-known (i.e. defaults to 0000) or can be easily discovered (printed/displayed on the device and physical access is possible) then security is compromised.
In theory a DOS attack is also possible by making repeated connection attempts, but this does still leave an opportunity for the legitimate central to connect.
Okay, this is a little late, but anyway: from v515 upwards you can use the AT+TYPEx command to change the authentication behaviour.
x can be, according to the docs:
0:Not need PIN Code (default)
1:Auth not need PIN
2:Auth with PIN
3:Auth and bond

Send data from an iOS app when connection is restored

I'm creating an app that allows the user to work without internet connection. When he wants to publish his progress to the web server it gets stored in the device's database. If he isn't connected to the internet I have to send it when he gets internet connection back.
How can I run the code to send the data to the database when internet connection is available again?
In Android I used a broadcast receiver to listen for a "connection changed" event to accomplish this but I don't seem to find a way in iOS to do the same.
You could try to check if the device has an active internet connection (3G and/or Wi-Fi for iPhone, Wi-Fi for iPad/iPod Touch), there are many ways to do that but the simplest in my opinion is to use Reachability.
Check this similar question for more informations about Reachability and how to implement it in your project. It can even be used in a if statement so you can make the user able to publish or not depending on his internet connection.

Resources