Skip to content

BluetoothWin32Authentication

Peter Foot edited this page Apr 29, 2017 · 5 revisions

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.

Examples

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

Secure Simple Pairing schemes

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.

Changes

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.

Testing

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.

Clone this wiki locally