-
-
Notifications
You must be signed in to change notification settings - Fork 209
BluetoothWin32Authentication
The class is used to respond to requests for authentication for Bluetooth devices.
It is supported only on the Microsoft stack on desktop Windows (MSFT+Win32 in my jargon). It should be possible to implement on BlueSoleil for instance, but I never managed to find the way to get their API to work -- it may need use of a message loop, similar to some stuff in Widcomm.
This class is generally used in a mode where a user supplied callback will be called when any device requires authentication. This is the mode that needs to be used for Bluetooth 2.1 Simple Secure Pairing (SSP). The callback will specify what type of pairing is required e.g. Legacy for tradional PIN pairing, or NumericComparison/JustWorks for v2.1 devices, and the user code in the callback method should response respectively, e.g by setting e.Pin or e.Confirm etc, see the full table of how to respond below. Also see the example code below.
(For traditional pairing (with a PIN code), it can also be used in a mode where an instance can be created specifying both the one device that is being connected to and the PIN string to use it will respond to that single device; it is used by BluetoothClient that way to support its {{Pin}} property.)
To confirm the pairing the callback method should do the following:
AuthenticationMethod etc | Action |
---|---|
Legacy | Then the pairing is using old-style PIN support, so the Pin property should be set |
NumericComparison | Then the Confirm propery needs to be set, but…… |
• If NumericComparison and JustWorksNumericComparison | • Then the user should be asked to confirm the pairing with a simple Yes/No. |
• If NumericComparison, and not JustWorksNumericComparison | • Then the user should be shown the NumberOrPasskey value and asked to confirm that the values displayed on both devices match. |
OutOfBand | ConfirmOob should be called -- this is untested |
→ | It seems that Passkey is "please input the passkey as displayed on the other device", and PasskeyNotification is "here's the passkey to type on the remote device, confirm that" |
PasskeyNotification | Then the user need to be shown the NumberOrPasskey value which needs to be typed on the remote device, and the Confirm propery needs to be set |
Passkey | Presumably set ResponseNumberOrPasskey as well as Confirm -- this is untested |
There are other properties on the BluetoothWin32AuthentionEventArgs for instance CallbackWithResult and PreviousNativeErrorCode. The reference documentation for this class is at BluetoothWin32Authentication
If you simply want to allow the pairing to go ahead when to SSP devices are connecting then handling the callback and setting e.Confirm=True will be enough -- but that is a little insecure...
If you want to initiate this pairing process then call BluetoothSecurity.PairRequest passing a null password.
If one wants to respond to PIN requests for one device with a known PIN then use the simple form which is initialized with an address and PIN.
BluetoothWin32Authentication authenticator
= new BluetoothWin32Authentication(remoteEP.Address, m_pin);
// when the peer is expected to require pairing, perhaps do some work.
authenticator.Dispose();
If one wants to see the PIN request, perhaps to be able to check the type of the peer by its address then use the form here which requests callbacks. (Note that this code assumes that 'Legacy' PIN-based pairing is being used; setting the Pin property will presumably have no effect if the authentication method being used is one of the v2.1 SSP forms).
Using pairer As New BluetoothWin32Authentication(AddressOf HandlerWithSsp ) ' or AddressOf Win32AuthCallbackHandler
Console.WriteLine("Hit Return to stop authenticating")
Console.ReadLine()
End Using
...
Sub Win32AuthCallbackHandler(ByVal sender As Object, ByVal e As InTheHand.Net.Bluetooth.BluetoothWin32AuthenticationEventArgs)
' Note we assume here that 'Legacy' pairing is being used,
' and thus we only set the Pin property!
Dim address As String = e.Device.DeviceAddress.ToString()
Console.WriteLine("Received an authentication request from address " + address)
'
' compare the first 8 hex numbers, this is just a special case because in the
' used scenario the model of the devices can be identified by the first 8 hex
' numbers, the last 4 numbers being the device specific part.
If address.Substring(0, 8).Equals("0099880D") OrElse _
address.Substring(0, 8).Equals("0099880E") Then
' send authentication response
e.Pin = "5276"
ElseIf (address.Substring(0, 8).Equals("00997788")) Then
' send authentication response
e.Pin = "ásdfghjkl"
End If
End Sub
' untested!
Sub HandlerWithSsp(ByVal sender As Object, ByVal e As InTheHand.Net.Bluetooth.BluetoothWin32AuthenticationEventArgs)
If e.AuthenticationMethod = BluetoothAuthenticationMethod.Legacy Then
' Call the old method above
Win32AuthCallbackHandler(sender, e)
ElseIf e.JustWorksNumericComparison = True Then
Dim rslt As DialogResult = MessageBox.Show("Allow device with address " & e.Device.DeviceAddress.ToString() & " to pair?")
If rslt = DialogResult.Yes Then
e.Confirm = True
End If
ElseIf e.AuthenticationMethod = BluetoothAuthenticationMethod.NumericComparison Then
Dim rslt As DialogResult = MessageBox.Show("Device with address " & e.Device.DeviceAddress.ToString() & " is wanting to pair." & _
" Confirm that it is displaying this six-digit number on screen: " & e.NumberOrPasskeyAsString)
If rslt = DialogResult.Yes Then
e.Confirm = True
End If
ElseIf e.AuthenticationMethod = BluetoothAuthenticationMethod.Passkey Then
Dim line As String = MyInputBox.Show("Device with address " & e.Device.DeviceAddress.ToString & " is wanting to pair." & _
" Please enter the six digit number that it is displaying on screen.")
If line IsNot Nothing Then
Dim pk As Integer = Integer.Parse(line)
If pk >= 0 AndAlso pk < 1000000 Then
e.ResponseNumberOrPasskey = pk
e.Confirm = True
End If
End If
Else
' TODO
End If
End Sub
The pairing method used follows this pattern: {{ if (either is pre-v2.1) then Legacy else if (Out-Of-Band channel) then OutOfBand else if (neither have "Man-in-the-Middle Protection Required") then (i.e. both have "Man-in-the-Middle Protection Not Required") Just-Works else Depending on the two devices' "IO Capabilities", either NumericComparison or Passkey. Passkey is used when one device has KeyboardOnly -- and the peer device isn't NoInputNoOutput.}}
TODO Add SSP forms descriptions.
As of February 2011 the callback mode supports Secure Simple Pairing on Windows 7 (and Vista SP2 etc). Various new properties have been added to the BluetoothWin32AuthentionEventArgs class: AuthenticationMethod, NumberOrPasskeyAsString, NumberOrPasskey, Confirm, JustWorksNumericComparison, ResponseNumberOrPasskey, etc. The AuthenticationMethod enum can have values: Legacy, OutOfBand, NumericComparison, Passkey, and PasskeyNotification.
I've managed to test: NumericComparison, and PasskeyNotification, as well as Legacy of course. When I first started testing I didn't have another Windows 7 box available with the MSFT stack so I tested with remote devices running BlueSoleil and Linux. (_Note _I have not managed to get authentication working with 32feet.NET on the BlueSoleil stack.) See the comments for one of our users who has: "tested SSP/NC between 2 Windows 7 PCs, a Windows 7 PC and an iPhone and a Windows 7 PC and a device we manufacture."
I have also tested the peer advertising each of the IO-Capabilities (using Linux BlueZ and its CreatePairedDevice API), and thus tested PasskeyNotification (when the peer advertised: 'KeyboardOnly').
I don't think it'll be possible to exercise the other methods: Passkey because that would need Windows to advertise KeyboardOnly and I can't find a way to do that. It also appears that Windows 7 might only have support for three I've tested, as MSDN for BluetoothSendAuthenticationResponseEx says: "Only the {"BLUETOOTH_AUTHENTICATION_METHOD_LEGACY, BLUETOOTH_AUTHENTICATION_METHOD_NUMERIC_COMPAIRISON and BLUETOOTH_AUTHENTICATION_METHOD_PASSKEY"} response types are valid." -- presumably there are two typos there: spelling "COMPAIRISON" and missing "..._NOTIFICATION" in the last.
32feet.NET - Personal Area Networking for .NET
In The Hand Ltd