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 http://docs.32feet.net/html/T_InTheHand_Net_Bluetooth_BluetoothWin32Authentication.htm

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.

Last edited Wed at 6:48 PM by alanjmcf, version 37

Comments

alanjmcf Wed at 6:43 PM 
Hi Mehrad. I'll change that sentence to remove the ambiguity! BlueSoleil is a quite different API... If you can any better way to interop with it let me know. :-) Alan

Mehrad1362 Apr 10 at 11:29 PM 
Alan,

Thanks again for getting back to us. I think I got a little bit confused by this part in this article saying "I've managed to test: NumericComparison, and PasskeyNotification, as well as Legacy of course. Starting my testing with BlueSoleil and Linux" and I was like how on earth I can't make this to work without considering the first thing you mentioned in this post about this method working only on Windows stack.
I have spent a fair amount of time and whatever I did, I've been asked for the passcode while using BlueSoleil and no way to get around it so far. I also had lots of problem disconnecting from the device as well.

Thanks again and I will keep you updated if I achieve something.

Mehrad

alanjmcf Apr 10 at 8:45 AM 
Mehrad. I don't we ever got authentication to work on BlueSoleil. Download the sources and see the code in InTheHand.Net.Personal\InTheHand.Net.Personal\Net.Bluetooth.BlueSoleil\BluesoleilSecurity.cs Add some debug prints and see what happens.

You could also try writing a simple Windows(Forms) program that uses the BlueSoleil API and see if you can get it to work there. Then make it work the same way in 32feet.NET. We can make changes if you get it working. Alan

Mehrad1362 Apr 4 at 6:18 AM 
Installing BlueSoleil (10.0.47 in specific) on Windows 7 causes the program to throw and exception when it hits the following line.
BluetoothWin32Authentication _win32Auth = new BluetoothWin32Authentication(HandleWin32Auth);

the exception is:
(0x80004005) “The operation completed successfully”


Since I am using this line only because BlueSoleil doesn't respond to PairRequest( ) with a pin integrated in the second parameter, this is a big issue for me atm.

I would really appreciate it if somebody could give me a hint on this.

Mehrad

alanjmcf Mar 10, 2011 at 2:26 PM 
Thanks sgurram. I'm not sure why one would want to change the scheme used... Anyway, see the "The pairing method used follows this pattern:" tree above, it is that logic which decides which scheme is used. So you'd need either OOB ability or both "Man-in-the-Middle Protection _Not_ Required", or one to be KeyboardOnly, and as far as I know one can't change them -- see e.g. http://social.msdn.microsoft.com/Forums/en-US/wdk/thread/fb14d5ba-b29b-4b45-98e6-512e4bed6b01/#b9e7696c-f388-4513-898c-64df8d4d65e8

sgurram Mar 9, 2011 at 8:00 PM 
I have tested the SSP between two windows 7 Panasonic CF-19 Toughbooks successfully. The SSP mode is "Numeric Comparison". Is there any way to specify what SSP mode of authentication to use when pairing between two Windows 7 devices (ver 2.1 Microsoft BT)? Thanks for the great work.,

alanjmcf Feb 10, 2011 at 9:38 PM 
Glad to hear its working well for you. Thanks for letting me know.

Thanks for doing all that testing too. I'll add a note of my testing when I get a moment -- but only have used BlueSoleil and Linux-BlueZ peers currently.

rickheines Feb 10, 2011 at 1:20 PM 
Alan,

Thanks for your efforts in adding SSP support. I have 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. In all cases the new code worked perfectly. Considering that I have a project review tomorrow, the timing couldn't have been better! If I'm ever in the UK I'll owe you a pint :).

-Rick