|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E" xml:lang="en"><title>Secure |
|
13 Simple Pairing (SSP)</title><shortdesc>Describes SSP.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <ul> |
|
15 <li id="GUID-D51EB888-7908-5F75-80B7-06B47994F22B"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-226FB791-0EA7-5756-893F-2839D4178E1E">Introduction</xref> </p> </li> |
|
16 <li id="GUID-F8B04B59-3A9B-54B5-9D64-A64F6A930A9E"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-2891BA26-F6C3-5F3C-A567-34D806A5DAA4">Overview</xref> </p> </li> |
|
17 <li id="GUID-744E1DDF-2908-569D-9C7A-E29223C6C9E1"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-FC295A44-D8D9-5835-A895-BFB85C5CB8B8">Symbian support for SSP</xref> </p> </li> |
|
18 <li id="GUID-2C9207CF-8924-568A-93F9-340AB3F2A1E4"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-E6541D2E-7881-5670-B0CF-F57AA64AC032">Implementing SSP notifiers</xref> </p> </li> |
|
19 <li id="GUID-3703505F-4F60-534C-B492-D83002FA9577"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-E1A7D7D3-891E-5A90-926D-3F946A5448A3">Using the Out of Band API</xref> </p> </li> |
|
20 <li id="GUID-67BC873E-DC42-5208-AE65-2564B1655C41"><p><xref href="GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E.dita#GUID-322A932E-5DC8-5CBB-BD3C-02F5CEDB060E/GUID-6C20C226-C4CE-5937-93D2-C1A89F00004C">Using the dedicated bonding API</xref> </p> </li> |
|
21 </ul> |
|
22 <section id="GUID-226FB791-0EA7-5756-893F-2839D4178E1E"><title>Introduction</title> <p>Secure |
|
23 Simple Pairing, introduced into Bluetooth v2.1, simplifies the user experience |
|
24 when pairing Bluetooth devices. </p> <p>This document describes the Symbian |
|
25 platform implementation of SSP. It describes the tasks that must be performed |
|
26 by UI creators to implement SSP and it describes how application developers |
|
27 can use Symbian APIs to pair with Bluetooth enabled devices using SSP. </p> <p><b>Scope</b> </p> <p>This document is intended for Symbian partners and developers |
|
28 implementing SSP on Symbian platform. It assumes that you are familiar with |
|
29 Bluetooth and with developing on Symbian platform. </p> <p><b>Purpose of SSP</b> </p> <p>SSP was introduced to simplify the user experience |
|
30 when pairing Bluetooth devices. Specifically: </p> <ul> |
|
31 <li id="GUID-63DD983D-4C9B-55A9-BC1E-B5F590576B51"><p>there is no need for |
|
32 the user to think of a number </p> </li> |
|
33 <li id="GUID-08AFD4B9-4B08-55CD-8A5A-83200F0D75AD"><p>the authentication process |
|
34 may differ for different devices and different services </p> </li> |
|
35 <li id="GUID-AC68A597-36ED-5FE4-8678-21FB8F4498BE"><p>all data transfer is |
|
36 encrypted </p> </li> |
|
37 </ul> </section> |
|
38 <section id="GUID-2891BA26-F6C3-5F3C-A567-34D806A5DAA4"><title>Overview</title> <p><b>The pairing model</b> </p> <p>Pre-SSP pairing is achieved by the user(s) |
|
39 entering a personal identification number (PIN) on one or both devices. Devices |
|
40 with no keypads, such as headsets, have their PINs (typically "0000" or "1234") |
|
41 hard-wired. This is now referred to as Legacy Paring. </p> <p>Under SSP, devices |
|
42 specify their authorisation requirements. The user may have to: </p> <ul> |
|
43 <li id="GUID-4B260DAC-E745-5FBE-95D7-3FD721A3F960"><p>press a button in response |
|
44 to a simple yes or no query </p> </li> |
|
45 <li id="GUID-E73EB3E7-5DBC-5326-9728-E086AA58B05A"><p>compare two automatically |
|
46 generated numbers and select 'yes' if they match or 'no' if they do not </p> </li> |
|
47 <li id="GUID-C7AE53AC-037A-5171-AED1-62AB0F0A1953"><p>enter a number on one |
|
48 or both devices </p> </li> |
|
49 <li id="GUID-E4FF8EB0-D0DD-5C39-891E-9732F53B4D7E"><p>do nothing </p> </li> |
|
50 </ul> <p>Once the devices have paired the user may be asked to authorise bonding. |
|
51 Bonded devices can subsequently pair with no user interaction. </p> <p><b>Key concepts</b> </p> <dl> |
|
52 <dlentry> |
|
53 <dt> Authentication</dt> |
|
54 <dd><p>Verification that a remote device is what it claims to be. Authentication |
|
55 may be unnecessary for some pairings (see Just Works), may require user intervention |
|
56 (see Man in the Middle) or may be performed through another channel (see Out |
|
57 of Band). </p> </dd> |
|
58 </dlentry> |
|
59 <dlentry> |
|
60 <dt> Authorisation</dt> |
|
61 <dd><p>In legacy pairing a remote device can be authorised after pairing such |
|
62 that it subsequently connects automatically without user intervention. Authorisation |
|
63 is on a per-service basis. See <b>bonding</b>. </p> </dd> |
|
64 </dlentry> |
|
65 <dlentry> |
|
66 <dt>Encryption</dt> |
|
67 <dd><p>Transmission of data between devices after SSP is always encrypted. |
|
68 Under legacy pairing data transmission is not always encrypted. </p> </dd> |
|
69 </dlentry> |
|
70 <dlentry> |
|
71 <dt> Man In The Middle (MITM) protection</dt> |
|
72 <dd><p>Authentication explicitly provided by the user before pairing can take |
|
73 place. Under SSP, devices and services have hard-wired authentication requirements |
|
74 as follows: MITM required, MITM not required (see Just Works) and MITM desired |
|
75 (subject to the user interface capabilities of the devices) </p> </dd> |
|
76 </dlentry> |
|
77 <dlentry> |
|
78 <dt> Just Works</dt> |
|
79 <dd><p>For some pairings there is little risk of a security breach so SSP |
|
80 provides a mechanism for devices to pair with no explicit user authentication. </p> </dd> |
|
81 </dlentry> |
|
82 <dlentry> |
|
83 <dt> Passkey</dt> |
|
84 <dd><p>In the context of a Symbian device, which always has both a display |
|
85 and a keypad, passkey authentication is used when pairing with a remote device |
|
86 which has a keypad but no display. The Symbian device displays a number which |
|
87 the user must enter using the keypad on the remote device </p> </dd> |
|
88 </dlentry> |
|
89 <dlentry> |
|
90 <dt> Out Of Band (OOB)</dt> |
|
91 <dd><p>Out of Band authentication is performed using a non-Bluetooth communication |
|
92 channel. The data required to open an MITM protected Bluetooth connection |
|
93 with a remote device is transmitted by other means. </p> </dd> |
|
94 </dlentry> |
|
95 <dlentry> |
|
96 <dt> Bonding</dt> |
|
97 <dd><p>Two devices may bond after athentication such that they can reconnect |
|
98 without user intervention. Bonding is achieved on a Symbian device by storing |
|
99 a link key. Symbian devices attempt to bond by default. The user or the remote |
|
100 device may specify that the devices do not bond. </p> </dd> |
|
101 </dlentry> |
|
102 <dlentry> |
|
103 <dt> Link key</dt> |
|
104 <dd><p>When a connection is authenticated a link key is created. The link |
|
105 key indicates the strength of authentication (legacy, authenticated or unauthenticated). |
|
106 The link key may be stored by the Symbian device and used to bond (the default |
|
107 behaviour) or discarded when the connection ends. The link key is not displayed |
|
108 to the user. </p> </dd> |
|
109 </dlentry> |
|
110 </dl> </section> |
|
111 <section id="GUID-FC295A44-D8D9-5835-A895-BFB85C5CB8B8"><title>Symbian support |
|
112 for SSP</title> <p><b>Components</b> </p> <p>Most |
|
113 of the changes are internal and transparent to system creators and developers. |
|
114 However, some new APIs added to the Bluetooth User Library allow application |
|
115 developers to use SSP features, and Licensees must implement some SSP specific |
|
116 notifiers. </p> <p>The diagram below shows the interfaces and interface classes |
|
117 required to implement SSP. </p> <p><b> Dedicated |
|
118 Bonding </b> </p> <p>Dedicated bonding is performed by the Bluetooth Pairing |
|
119 Server. Applications can use the <xref href="GUID-8E97F127-DA49-3BB6-B274-348138B425DF.dita"><apiname>RBluetoothDedicatedBondingInitiator</apiname></xref> API |
|
120 to request bonding with a specified Bluetooth device. </p> <p><b> Out of Band Data</b> </p> <p>Out of Band pairing data can be passed to |
|
121 the Bluetooth Pairing Server. The server can use the supplied data to pair |
|
122 with the specified device. Applications can also use the <xref href="GUID-C92BBABD-AE1B-325B-9791-95875272AAAC.dita"><apiname>RBluetoothOobData</apiname></xref> API |
|
123 to retrieve OOB data for the local device to be passed to remote devices. </p> <p><b> Numeric Comparison Notifier </b> </p> <p>The Bluetooth sub-system requires |
|
124 a Numeric Comparison Notifier to be provided by the UI. The notifier must |
|
125 handle <xref href="GUID-D3F5500E-2BCD-3BB9-8B6B-5716C22FAB05.dita"><apiname>TBTNumericComparisonParams</apiname></xref> and return a boolean |
|
126 value which indicates the user's decision. </p> <p><b> Passkey Entry Notifier </b> </p> <p>The Bluetooth sub-system requires |
|
127 a Passkey Entry Notifier to be provided by the UI. The notifier must handle <xref href="GUID-F4DBF857-2192-3177-B431-8499907E41AF.dita"><apiname>TBTPasskeyDisplayParams</apiname></xref> and <xref href="GUID-EB94B14B-F836-3FA1-88CD-51FC0528D76A.dita"><apiname>TBTPasskeyDisplayUpdateParams</apiname></xref>. </p> <p><b> Data |
|
128 Types </b> </p> <p>SSP specific data is stored and manipulated using the following |
|
129 types (significant functions and fields shown only). These types are used |
|
130 in various device and service related APIs. They are defined in <filepath>bt_sock.h</filepath> and <filepath>btdevice.h</filepath>. </p> <p> <codeph>#include <bt_sock.h> </codeph> </p> <codeblock id="GUID-3CF4FEFE-96AC-5CF3-A522-397754161A50" xml:space="preserve"> |
|
131 enum TBluetoothMitmProtection |
|
132 { |
|
133 EMitmNotRequired = 0x0, // No Man-in-the-Middle authentication is not required. |
|
134 EMitmDesired = 0x1, // Man-in-the-Middle authentication should be used where possible. |
|
135 EMitmRequired = 0x2 // Man-in-the-Middle authentication is required. |
|
136 }; |
|
137 </codeblock> <p> <xref href="GUID-C0341B1C-E358-3C7B-B673-37103E2AF0A3.dita"><apiname>TBTAccessRequirements</apiname></xref> </p> <codeblock id="GUID-2EA4EA4A-AFC4-5BB2-851F-0891EC42FF6F" xml:space="preserve"> |
|
138 class TBTAccessRequirements |
|
139 { |
|
140 public: |
|
141 ... |
|
142 IMPORT_C void SetAuthentication( TBluetoothMitmProtection aPreference ); |
|
143 IMPORT_C TBluetoothMitmProtection MitmProtection() const; |
|
144 ... |
|
145 |
|
146 |
|
147 private: |
|
148 enum TBTServiceSecuritySettings |
|
149 { |
|
150 EAuthenticate = 0x01, |
|
151 EAuthorise = 0x02, |
|
152 EEncrypt = 0x04, |
|
153 EDenied = 0x08, |
|
154 EMitm = 0x30, // 2 bit field for MITM |
|
155 }; |
|
156 |
|
157 enum TBTAccessRequirementsMitmProtection |
|
158 { |
|
159 EAccessRequirementsMitmUndefined = 0x00, |
|
160 EAccessRequirementsMitmNotRequired = 0x10, |
|
161 EAccessRequirementsMitmDesired = 0x20, |
|
162 EAccessRequirementsMitmRequired = 0x30 |
|
163 }; |
|
164 };</codeblock> <p> <xref href="GUID-BC29B643-2CE8-30C1-BF41-4D2B5585DC81.dita"><apiname>TBTServiceSecurity</apiname></xref> </p> <codeblock id="GUID-28168FA1-2CF7-59BE-B77B-484991491810" xml:space="preserve"> |
|
165 class TBTServiceSecurity |
|
166 { |
|
167 public: |
|
168 ... |
|
169 IMPORT_C void SetAuthentication( TBluetoothMitmProtection aPreference ); |
|
170 IMPORT_C TBool AuthenticationRequired() const; |
|
171 IMPORT_C TBluetoothMitmProtection MitmProtection() const; |
|
172 ... |
|
173 |
|
174 private: |
|
175 TBTAccessRequirements iSecurityRequirements; // Whether the service requires authentication, authorisation, encryption or min passkey len. |
|
176 }; |
|
177 |
|
178 typedef TPckgBuf<TBTServiceSecurity> TBTServiceSecurityPckg; // Package definition for securty settings |
|
179 </codeblock> <p> <codeph>#include <btdevice.h> </codeph> </p> <p> <xref href="GUID-7E0FA8C7-DEB4-3D86-901E-68DAC99DCA40.dita"><apiname>TBTDeviceSecurity</apiname></xref> </p> <codeblock id="GUID-DCC63DB6-6D3F-5B32-836D-973E65305B13" xml:space="preserve"> |
|
180 class TBTDeviceSecurity |
|
181 { |
|
182 public: |
|
183 |
|
184 // Enumeration to provide select MITM protection required. |
|
185 |
|
186 enum TMitmRequired |
|
187 { |
|
188 EMitmUnspecified, // No specific MITM protection requirements |
|
189 EMitmRequired // Require the link is MITM protected |
|
190 }; |
|
191 |
|
192 public: |
|
193 |
|
194 ... |
|
195 IMPORT_C void SetNoAuthenticate(TBool aDecision); |
|
196 IMPORT_C void SetMitmRequirements(TMitmRequired aDecision); |
|
197 ... |
|
198 IMPORT_C TBool NoAuthenticate() const; |
|
199 IMPORT_C TMitmRequired MitmRequirements() const; |
|
200 ... |
|
201 |
|
202 public: |
|
203 // Enumeration to assist in parsing of security settings. |
|
204 enum TBTDeviceSecuritySettings |
|
205 { |
|
206 ENoAuthenticate = 0x01, // Don't authenticate the link @deprecated |
|
207 ENoAuthorise = 0x02, // Don't authorise the connection |
|
208 EEncrypt = 0x04, // Encrypt the link |
|
209 EBanned = 0x08, // Don't connect to the device |
|
210 EMitmProtectionRequired = 0x10, // Require the link is MITM protected |
|
211 }; |
|
212 }; |
|
213 </codeblock> </section> |
|
214 <section id="GUID-E6541D2E-7881-5670-B0CF-F57AA64AC032"><title>Implementing |
|
215 SSP notifiers</title> <p><b>Introdution</b> </p> <p>The |
|
216 Bluetooth sub-system has no user interface. It uses the Symbian <xref href="GUID-E049772D-A96F-592F-AF59-C9B69E8D24C1-GENID-1-8-1-3-1-1-11-1-4-1.dita">notifier |
|
217 framework</xref> for user interaction when pairing. The UI system must provide |
|
218 a notifier, in plug-in form, for each user interaction required by SSP. The |
|
219 notifier must receive data in a specified format from the Bluetooth sub-system, |
|
220 display appropriate controls in a dialog on the screen, respond to the user's |
|
221 input and send data back to the Bluetooth sub-system in a specified format. </p> <p>This |
|
222 document assumes that you already have Bluetooth notifiers in your system. |
|
223 It describes the key aspects of adding notifiers for SSP. The structures, |
|
224 types and constants described below are defined in <filepath>BTExtNotifiers.h</filepath>. |
|
225 You can add notifiers to an existing plug-in or create a new plug-in. </p> <p>Notifiers |
|
226 are typically implemented as sleeping dialogs. A sleeping dialog has its resources |
|
227 allocated when its application (in this case the Uikon Server) is started. |
|
228 A sleeping dialog can therefore be displayed (roused) safely under low memory |
|
229 conditions. </p> <p><b>Notes: </b> </p> <ul> |
|
230 <li id="GUID-8F9A2CA6-0481-55EB-8458-076AA869CF1E"><p>This document does not |
|
231 describe how to implement an ECOM plug-in or a sleeping dialog. </p> </li> |
|
232 <li id="GUID-0BA5CB89-F09C-5150-82C5-2169503FF961"><p>Customisation Kit Licensees |
|
233 can find an example notifier implementation here: <filepath>sf/mw/classicui/commonuisupport/uikon/examples/notifier1/</filepath> </p> </li> |
|
234 </ul> <p><b>Numeric |
|
235 Comparison Notifier</b> </p> <p>A numeric comparison notifier is required |
|
236 for SSP Man in the Middle (MITM) authentication when the remote device is |
|
237 capable of displaying a number to the the user and accepting a yes or no response |
|
238 from the user. The notifier must display an automatically generated number |
|
239 and invite the user to confirm (yes or no) that the number is the same as |
|
240 the number displayed on the remote device. The notifier must return the user's |
|
241 response. </p> <p>The Bluetooth Security Manager uses the following code to |
|
242 ask the notifier framework to display the Numeric Comparison Notifier </p> <codeblock id="GUID-C797A612-4AD7-5DE1-854E-3398945A4957" xml:space="preserve"> |
|
243 |
|
244 // defined in header file(s) |
|
245 |
|
246 TBTDevAddr iDevAddr ; |
|
247 RNotifier iNotifier ; |
|
248 TUint32 iNumericValue ; |
|
249 TBool iInternallyInitiated ; |
|
250 TBTNumericComparisonParamsPckg iNumericComparisonParamsPckg ; |
|
251 TPckgBuf<TBool> iResultPckg ; |
|
252 // |
|
253 |
|
254 void CBTNumericComparator::DoRequest() |
|
255 { |
|
256 // Start the RNotifier plugin that deals with authorisation. |
|
257 |
|
258 ... |
|
259 |
|
260 TBTDeviceName deviceName = KNullDesC ; |
|
261 |
|
262 iNumericComparisonParamsPckg = TBTNumericComparisonParams( iDevAddr, |
|
263 deviceName, |
|
264 iNumericValue, |
|
265 TBTNumericComparisonParams::ERemoteCanConfirm, |
|
266 iInternallyInitiated); |
|
267 |
|
268 iNotifier.StartNotifierAndGetResponse( iStatus, |
|
269 KBTNumericComparisonNotifierUid, |
|
270 iNumericComparisonParamsPckg, |
|
271 iResultPckg); |
|
272 SetActive(); |
|
273 } |
|
274 </codeblock> <p>From the code above you can see that the Numeric Comparision |
|
275 Notifier is identified by the UID<codeph>KBTNumericComparisonNotifierUid</codeph> and |
|
276 that it must handle data in <xref href="GUID-D3F5500E-2BCD-3BB9-8B6B-5716C22FAB05.dita"><apiname>TBTNumericComparisonParams</apiname></xref> (which |
|
277 is packaged into <codeph>TBTNumericComparisonParamsPckg</codeph> for inter-process |
|
278 transfer). </p> <p>The code fragment below shows how to extract the numeric |
|
279 comparison data within a notifier. </p> <p>NOTE: You will need to implement |
|
280 all of the virtual functions in <xref href="GUID-4E967403-417B-3340-B168-9FAF6565FEFF.dita"><apiname>MEikSrvNotifierBase2.</apiname></xref> </p> <codeblock id="GUID-36408990-3292-531C-B15E-E88575CD0578" xml:space="preserve"> |
|
281 class CNumericComparisonNotifier : public CEikDialog, public MEikSrvNotifierBase2 |
|
282 { |
|
283 public: |
|
284 |
|
285 ... |
|
286 |
|
287 // from MEikSrvNotifierBase2 |
|
288 void StartL ( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) ; |
|
289 |
|
290 ... |
|
291 |
|
292 void Complete( TBool aDecision, TInt aReason ) ; |
|
293 |
|
294 private: |
|
295 TInt iRepySlot ; |
|
296 TNotifierInfo iInfo ; |
|
297 RMessage2 iMessage ; |
|
298 TBTNumeriComparisonParamsPckg iNumericComparisonParamsPckg ; |
|
299 TBTDevAddr iAddr ; |
|
300 TBTDeviceName iName ; |
|
301 TUint32 iNumericalValue ; |
|
302 |
|
303 } ; |
|
304 |
|
305 |
|
306 |
|
307 //-------------------------------- |
|
308 |
|
309 ... |
|
310 |
|
311 void CNumericComparisionNotifier::StartL( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) |
|
312 { |
|
313 |
|
314 iMessage = RMessage2( aMessage ) ; // keep a copy ofthe message so that it can be completed later. |
|
315 iReplySlot = aReplySlot ; // copy the reply slot too |
|
316 |
|
317 // Extract the comparison parameters from the buffer |
|
318 |
|
319 iNumericComparisonParamsPckg.Copy( aBuffer ) ; |
|
320 |
|
321 iAddr = iNumericComparisonParamsPckg().DeviceAddress() ; |
|
322 iName = iNumericComparisonParamsPckg().DeviceName() ; |
|
323 iNumericalValue = iNumericComparisonParamsPckg().NumericalValue() ; |
|
324 |
|
325 ... |
|
326 |
|
327 RouseSleepingDialog() ; |
|
328 |
|
329 } |
|
330 |
|
331 </codeblock> <p>Your dialog must display <codeph>iNumericalValue</codeph> and |
|
332 ask the user if the number displayed is the same as the number displayed on |
|
333 the other Bluetooth device. The user must be able to select 'Yes' or 'No'. </p> <p>The <codeph>StartL()</codeph> function |
|
334 above must return quickly so it must not wait for the user's response. Your |
|
335 notifier must complete the message (<codeph>iMessage</codeph>) as shown below |
|
336 when the user enters a response. </p> <codeblock id="GUID-7C313F8D-F521-541D-8294-686339633F43" xml:space="preserve"> |
|
337 void CNumericComparisionNotifier::Complete( TBool aDecision, TInt aReason ) |
|
338 { |
|
339 if ( aReason == KErrNone ) |
|
340 { |
|
341 TInt err = iMessage.Write( iReplySlot, TPckgC<TBool>( aDecision ) ) ; |
|
342 iMessage.Complete( err ) ; |
|
343 } |
|
344 else |
|
345 { |
|
346 iMessage.Complete( aReason ) ; |
|
347 } |
|
348 } |
|
349 </codeblock> <p><b>Passkey |
|
350 Notifier</b> </p> <p>A passkey notifier is required for SSP MITM authentication |
|
351 when the user must type a number on a remote device which has a keypad and |
|
352 no display. The notifier displays the number that the user must type. In the |
|
353 code below the notifier also displays a '*' character as the user types each |
|
354 digit into the remote device. </p> <p>The Bluetooth Security Manager uses |
|
355 the following code to ask the Notifier Framework to display the passkey notifier. </p> <codeblock id="GUID-C9F126EB-D3F2-5F08-AF50-64123BB5455F" xml:space="preserve"> |
|
356 |
|
357 // defined in header file(s) |
|
358 |
|
359 TBTDevAddr iDevAddr ; |
|
360 RNotifier iNotifier ; |
|
361 TUint32 iNumericValue ; // the passkey number |
|
362 TBool iInternallyInitiated ; |
|
363 TBTPasskeyDisplayParamsPckg iPasskeyDisplayParamsPckg ; |
|
364 TBTDeviceNameUpdateParamsPckg iDeviceNameUpdateParamsPckg; |
|
365 TBuf8<1> iResultPckg ; |
|
366 |
|
367 void CBTPasskeyEntry::DoRequest() |
|
368 { |
|
369 // Start the RNotifier plugin that deals with authorisation. |
|
370 |
|
371 ... |
|
372 |
|
373 TBTDeviceName deviceName ; |
|
374 |
|
375 deviceName = KNullDesC ; |
|
376 |
|
377 iPasskeyDisplayParamsPckg = TBTPasskeyDisplayParams( iDevAddr, |
|
378 deviceName, |
|
379 iNumericValue, |
|
380 iInternallyInitiated ) ; |
|
381 |
|
382 iNotifier.StartNotifierAndGetResponse( iStatus, |
|
383 KBTPasskeyDisplayNotifierUid, |
|
384 iPasskeyDisplayParamsPckg, |
|
385 iResultPckg ) ; |
|
386 SetActive() ; |
|
387 |
|
388 } |
|
389 |
|
390 </codeblock> <p>From the code above you can see that the Passkey Notifier |
|
391 is identified by the UID<codeph>KBTPasskeyNotifierUid</codeph> and that it |
|
392 must handle data in <xref href="GUID-F4DBF857-2192-3177-B431-8499907E41AF.dita"><apiname>TBTPasskeyDisplayParams</apiname></xref> (which is packaged |
|
393 into <codeph>TBTPasskeyDisplayParamsPckg</codeph> for inter-process transfer). </p> <p>As |
|
394 the user enters passkey digits into the remote device the Security Manager |
|
395 also uses <codeph>RNotifier::UpdateNotifierAndGetResponse()</codeph> to send <xref href="GUID-EB94B14B-F836-3FA1-88CD-51FC0528D76A.dita"><apiname>TBTPasskeyDisplayUpdateParams</apiname></xref> (packaged |
|
396 in <xref href="GUID-D6CA0DDB-1CD0-32F1-BBB5-7E280E1C4779.dita"><apiname>TBTPasskeyDisplayUdateParamsPckg</apiname></xref>) to the notifier. Your |
|
397 notifier must use this information to reflect the key presses on the remote |
|
398 device. </p> <p>The code fragment below shows how to extract the passkey data |
|
399 within a notifier. </p> <p>NOTE: You will need to implement all of the virtual |
|
400 functions in <xref href="GUID-4E967403-417B-3340-B168-9FAF6565FEFF.dita"><apiname>MEikSrvNotifierBase2.</apiname></xref> </p> <codeblock id="GUID-B38F7512-B091-5F93-86F1-EA740DAD7509" xml:space="preserve"> |
|
401 class CPasskeyNotifier : public CEikDialog, public MEikSrvNotifierBase2 |
|
402 { |
|
403 public: |
|
404 |
|
405 ... |
|
406 |
|
407 // from MEikSrvNotifierBase2 |
|
408 void StartL( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) ; |
|
409 TPtrC8 UpdateL( const TDesC8& aBuffer ) ; // new information |
|
410 |
|
411 ... |
|
412 |
|
413 private: |
|
414 TInt iRepySlot ; |
|
415 TNotifierInfo iInfo ; |
|
416 RMessage2 iMessage ; |
|
417 TBTPasskeyDisplayParamsPckg iPasskeyDisplayParamsPckg ; |
|
418 TBTDevAddr iAddr ; |
|
419 TBTDeviceName iName ; |
|
420 TUint32 iNumericalValue ; // the passkey number |
|
421 |
|
422 } ; |
|
423 |
|
424 //-------------------------------- |
|
425 |
|
426 ... |
|
427 |
|
428 void CPasskeyNotifier::StartL( const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage ) |
|
429 { |
|
430 |
|
431 iMessage = RMessage2(aMessage); // keep a copy ofthe message so that it can be completed later. |
|
432 iReplySlot = aReplySlot ; // copy the reply slot too |
|
433 |
|
434 // Extract the comparison parameters from the buffer |
|
435 |
|
436 iPasskeyDisplayParamsPckg.Copy( aBuffer ) ; |
|
437 |
|
438 iAddr = iPasskeyDisplayParamsPckg().DeviceAddress() ; |
|
439 iName = iPasskeyDisplayParamsPckg().DeviceName() ; |
|
440 iNumericValue = iPasskeyDisplayParamsPckg().NumericalValue() ; |
|
441 |
|
442 |
|
443 ... |
|
444 |
|
445 RouseSleepingDialog() ; // display the passkey |
|
446 |
|
447 ... |
|
448 |
|
449 } |
|
450 |
|
451 void CPasskeyNotifier::UpdateL( const TDesC8& aBuffer ) |
|
452 { |
|
453 |
|
454 // extract the contents of the buffer |
|
455 |
|
456 TBTNotifierUpdateParamsPckg2 pckgRaw ; |
|
457 pckgRaw.Copy( aBuffer.Left( pckgRaw.MaxLength() ) ) ; |
|
458 |
|
459 // update the dialog to reflect the keys pressed on the remote device |
|
460 |
|
461 if ( pckgRaw().Type() == TBTNotifierUpdateParams2::EPasskeyDisplay ) |
|
462 { |
|
463 TBTPasskeyDisplayUpdateParamsPckg pckg ; |
|
464 pckg.Copy( aBuffer ) ; |
|
465 HCIPasskeyEntryNotificationType keypressNotification = pckg().KeypressNotification() ; |
|
466 |
|
467 switch (keypressNotification) |
|
468 { |
|
469 case EPasskeyEntryStarted : |
|
470 { |
|
471 break ; |
|
472 } |
|
473 case EPasskeyDigitEntered : |
|
474 { |
|
475 // display '*' |
|
476 break ; |
|
477 } |
|
478 case EPasskeyDigitDeleted : |
|
479 { |
|
480 // remove '*', reposition cursor |
|
481 break ; |
|
482 } |
|
483 case EPasskeyCleared : |
|
484 { |
|
485 // clear display, reposition cursor |
|
486 break ; |
|
487 } |
|
488 case EPasskeyEntryCompleted : |
|
489 { |
|
490 // hide the dialog |
|
491 ExitSleepingDialog() ; |
|
492 break; |
|
493 } |
|
494 default : |
|
495 break ; |
|
496 } |
|
497 else if( pckgRaw().Type() == TBTNotifierUpdateParams2::EDeviceName ) |
|
498 { |
|
499 // handle name update |
|
500 } |
|
501 return KNullDesC8() ; |
|
502 } |
|
503 |
|
504 |
|
505 |
|
506 </codeblock> </section> |
|
507 <section id="GUID-E1A7D7D3-891E-5A90-926D-3F946A5448A3"><title>Out of Band |
|
508 (OOB) authentication</title> <p><b>Introduction</b> </p> <p>Out |
|
509 of Band authentication is achieved using a communication method other than |
|
510 Bluetooth. Once OOB authentication has succeeded an encrypted Bluetooth channel |
|
511 is opened between the two devices. </p> <p>The OOB API, <xref href="GUID-C92BBABD-AE1B-325B-9791-95875272AAAC.dita"><apiname>RBluetoothOobData</apiname></xref>, |
|
512 allows an application handling OOB authentication to provide pairing information |
|
513 for a remote device. </p> <p> <xref href="GUID-C92BBABD-AE1B-325B-9791-95875272AAAC.dita"><apiname>RBluetoothOobData</apiname></xref> allows |
|
514 an application handling OOB authentication to retrieve pairing information |
|
515 for the local device. </p> <p><b>Using |
|
516 the OOB API</b> </p> <p>The OOB data API is provided by the Pairing Server |
|
517 (part of the Security Manager). </p> <codeblock id="GUID-B474C4DA-7FBE-5ABF-9124-BF1B3A899EE0" xml:space="preserve"> |
|
518 |
|
519 #include <pairing.h> |
|
520 |
|
521 RBluetoothPairingServer pairingServer ; |
|
522 RBluetoothOobData OobData ; |
|
523 |
|
524 |
|
525 // Connect to the Pairing server |
|
526 |
|
527 TInt err = pairingServer.connect() ; |
|
528 |
|
529 // Paring session |
|
530 |
|
531 err = OobData.Open( iPairingServer ) ; |
|
532 |
|
533 |
|
534 // Use the API pass hash and randomizer values to and from the pairing server. |
|
535 |
|
536 ... |
|
537 |
|
538 |
|
539 // Tidy up |
|
540 |
|
541 OobData.Close() ; |
|
542 PairingServer.Close() ; |
|
543 |
|
544 </codeblock> <p>The API has three primary functions: </p> <p> <codeph>RefreshLocalOobData()</codeph> - |
|
545 This function causes the Bluetooth controller to generate new hash and randomizer |
|
546 values for the local device. To retrieve the new values call <codeph>ReadLocalOobData()</codeph> </p> <p> <codeph>ReadLocalOobData()</codeph> - |
|
547 This function returns the hash and randomizer values that the Bluetooth controller |
|
548 is currently using. </p> <p> <codeph>ProvideRemoteOobData()</codeph> - Use |
|
549 this function to pass OOB data about a remote device to the Bluetooth sub-system. |
|
550 Three versions of the function are available which take slightly different |
|
551 parameters. Information provided using one of these functions can be cleared |
|
552 using <codeph>ClearRemoteOobData()</codeph>. </p> </section> |
|
553 <section id="GUID-6C20C226-C4CE-5937-93D2-C1A89F00004C"><title>Dedicated bonding</title> <p><b>Introduction</b> </p> <p>Dedicated bonding is intended for applications |
|
554 which bond with a specific Bluetooth device. </p> <p><b>Using the dedicated bonding API</b> </p> <codeblock id="GUID-BA1AF395-EFB7-5E12-9E94-D83504876401" xml:space="preserve"> |
|
555 |
|
556 #include <pairing.h> |
|
557 |
|
558 RBluetoothPairingServer pairingServer ; |
|
559 RBluetoothDedicatedBondingInitiator bonder ; |
|
560 TBTDevAddr addr ; |
|
561 TRequstStatus status ; |
|
562 |
|
563 |
|
564 // Connect to the Pairing server |
|
565 |
|
566 TInt err = pairingServer.connect() ; |
|
567 |
|
568 |
|
569 // Use the Bluetooth address of the remote device bonder.Start( pairingServer, addr, status ) ; |
|
570 |
|
571 |
|
572 // Wait for the request to complete |
|
573 |
|
574 User::WaitForRequest(status); |
|
575 |
|
576 |
|
577 // Close the connection with the bonder (Must be closed before bonding with another device) |
|
578 |
|
579 bonder.Close(); |
|
580 |
|
581 pairingServer.Close() ; |
|
582 |
|
583 </codeblock> </section> |
|
584 </conbody></concept> |