|
1 /* |
|
2 * Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 // INCLUDE FILES |
|
23 #include "IptvDebug.h" |
|
24 #include <sysutil.h> |
|
25 |
|
26 #include <3des.h> // For C3DES |
|
27 #include <centralrepository.h> // link against centralrepository.lib |
|
28 #include <e32math.h> |
|
29 #include <mmtsy_names.h> |
|
30 |
|
31 #include "ciptvsecureprovisioningparameters.h" |
|
32 |
|
33 // EXTERNAL DATA STRUCTURES |
|
34 |
|
35 // EXTERNAL FUNCTION PROTOTYPES |
|
36 |
|
37 // CONSTANTS |
|
38 const TUid KCRUidPnpUtil = {0x1020433A}; |
|
39 const TInt KMaxKeyInfoLength = 20; |
|
40 const TInt KNonceLength = 8; |
|
41 const TUint32 KPnPUtilNonce = 0x00000002; |
|
42 const TUint32 KPnPUtilHomeMcc = 0x00000004; |
|
43 const TUint32 KPnPUtilHomeMnc = 0x00000005; |
|
44 const TUint32 KPnPUtilKeyInfo = 0x00000008; |
|
45 _LIT8( K3DesKey, "111111111111111111111111" ); |
|
46 |
|
47 // MACROS |
|
48 |
|
49 // LOCAL CONSTANTS AND MACROS |
|
50 |
|
51 // MODULE DATA STRUCTURES |
|
52 |
|
53 // LOCAL FUNCTION PROTOTYPES |
|
54 |
|
55 // FORWARD DECLARATIONS |
|
56 |
|
57 // ============================= LOCAL FUNCTIONS =============================== |
|
58 |
|
59 // ============================ MEMBER FUNCTIONS =============================== |
|
60 |
|
61 // ----------------------------------------------------------------------------- |
|
62 // CIptvSecureProvisioningParameters::ConstructL |
|
63 // Symbian 2nd phase constructor can leave. |
|
64 // ----------------------------------------------------------------------------- |
|
65 // |
|
66 void CIptvSecureProvisioningParameters::ConstructL() |
|
67 { |
|
68 User::LeaveIfError( iServer.Connect() ); |
|
69 User::LeaveIfError( iServer.LoadPhoneModule( KMmTsyModuleName ) ); |
|
70 User::LeaveIfError( iPhone.Open( iServer, KMmTsyPhoneName ) ); |
|
71 User::LeaveIfError( iPhone.Initialise() ); |
|
72 |
|
73 iRepository = CRepository::NewL( KCRUidPnpUtil ); |
|
74 |
|
75 #ifndef __WINS__ // calling C3DESEncryptor::NewL crashes emulator |
|
76 iEncryptor = C3DESEncryptor::NewL( K3DesKey ); |
|
77 #endif |
|
78 } |
|
79 |
|
80 // ----------------------------------------------------------------------------- |
|
81 // CIptvSecureProvisioningParameters::NewL |
|
82 // Two-phased constructor. |
|
83 // ----------------------------------------------------------------------------- |
|
84 // |
|
85 CIptvSecureProvisioningParameters* CIptvSecureProvisioningParameters::NewL() |
|
86 { |
|
87 CIptvSecureProvisioningParameters* self = new( ELeave ) CIptvSecureProvisioningParameters; |
|
88 |
|
89 CleanupStack::PushL( self ); |
|
90 self->ConstructL(); |
|
91 CleanupStack::Pop(self); |
|
92 |
|
93 return self; |
|
94 } |
|
95 |
|
96 |
|
97 // Destructor |
|
98 CIptvSecureProvisioningParameters::~CIptvSecureProvisioningParameters() |
|
99 { |
|
100 delete iRepository; |
|
101 #ifndef __WINS__ |
|
102 delete iEncryptor; |
|
103 #endif |
|
104 iPhone.Close(); |
|
105 iServer.Close(); |
|
106 } |
|
107 |
|
108 // ----------------------------------------------------------------------------- |
|
109 // CIptvSecureProvisioningParameters::SecureProvisioningUrlParametersL() |
|
110 // ----------------------------------------------------------------------------- |
|
111 // |
|
112 HBufC* CIptvSecureProvisioningParameters::SecureProvisioningUrlParametersL() |
|
113 { |
|
114 IPTVLOGSTRING_LOW_LEVEL("CIptvService::SecureProvisioningUrlParametersL() start"); |
|
115 |
|
116 // home country code and home network id |
|
117 |
|
118 FetchHomeNetworkInfoL(); |
|
119 |
|
120 RMobilePhone::TMobilePhoneNetworkCountryCode homeMcc = HomeMccL(); |
|
121 RMobilePhone::TMobilePhoneNetworkIdentity homeMnc = HomeMncL(); |
|
122 |
|
123 const TInt HomeCountryCodeLength = 4; |
|
124 const TInt HomeNetworkCodeLength = 8; |
|
125 TBuf<HomeCountryCodeLength> hmcc16; |
|
126 TBuf<HomeNetworkCodeLength> hmnc16; |
|
127 hmcc16.Copy( homeMcc ); |
|
128 hmnc16.Copy( homeMnc ); |
|
129 |
|
130 // keyinfo, nonce |
|
131 TBuf8<KMaxKeyInfoLength> keyInfo; |
|
132 TBuf<KMaxKeyInfoLength> keyInfo16; |
|
133 GetKeyInfoL( keyInfo ); |
|
134 keyInfo16.Copy( keyInfo ); |
|
135 TBuf8<KNonceLength> nonce; |
|
136 TBuf<KNonceLength> nonce16; |
|
137 TInt timeout( 0 ); |
|
138 CreateNewNonceL( timeout, nonce ); |
|
139 nonce16.Copy( nonce ); |
|
140 |
|
141 // product model |
|
142 TBuf8<KSysUtilVersionTextLength> deviceinfo; |
|
143 TBuf<KSysUtilVersionTextLength> deviceinfo16; |
|
144 FetchProductModelL( deviceinfo ); |
|
145 deviceinfo16.Copy( deviceinfo ); |
|
146 |
|
147 // 1. Keyinfo |
|
148 // 2. Nonce |
|
149 // 3. Home MCC |
|
150 // 4. Home MNC |
|
151 // 5. Network (current) MCC |
|
152 // 6. Network MNC |
|
153 // 7. Version |
|
154 // 8. deviceinfo |
|
155 |
|
156 _LIT( KVersionDes, "NPnP-MSS60-1.01" ); |
|
157 const TInt KVersionDesLength = 16; |
|
158 |
|
159 TBuf<KVersionDesLength> version16; |
|
160 version16 = KVersionDes; |
|
161 |
|
162 // These are for the test service, comments kept here until we get the real thing up. |
|
163 //version16 = _L("email-0.1"); |
|
164 //deviceinfo16 = _L("n80"); |
|
165 |
|
166 _LIT(KParameterFormatDes, |
|
167 "?sType=4&Key=%S&Nonce=%S&MCC=%S&MNC=%S&cVersion=%S&deviceinfo=%S&VCSW=1&action=activate"); |
|
168 const TInt KParameterFormatDesLength = 150; |
|
169 |
|
170 HBufC* parameters = HBufC::NewL( |
|
171 KParameterFormatDesLength + |
|
172 keyInfo16.Length() + |
|
173 nonce16.Length() + |
|
174 hmcc16.Length() + |
|
175 hmnc16.Length() + |
|
176 KVersionDesLength + |
|
177 deviceinfo16.Length() ); |
|
178 |
|
179 TPtr parametersPtr( parameters->Des() ); |
|
180 |
|
181 parametersPtr.Format( |
|
182 KParameterFormatDes, |
|
183 &keyInfo16, |
|
184 &nonce16, |
|
185 &hmcc16, |
|
186 &hmnc16, |
|
187 &version16, |
|
188 &deviceinfo16); |
|
189 |
|
190 IPTVLOGSTRING2_HIGH_LEVEL( "%S", ¶metersPtr ); |
|
191 |
|
192 IPTVLOGSTRING_LOW_LEVEL("CIptvService::SecureProvisioningUrlParametersL() exit"); |
|
193 return parameters; |
|
194 } |
|
195 |
|
196 // ----------------------------------------------------------------------------- |
|
197 // CIptvSecureProvisioningParameters::FetchProductModelL() |
|
198 // ----------------------------------------------------------------------------- |
|
199 // |
|
200 void CIptvSecureProvisioningParameters::FetchProductModelL( TDes8& aModel ) |
|
201 { |
|
202 HBufC* tmpVersion = HBufC::NewLC( KSysUtilVersionTextLength ); |
|
203 TPtr ptr( tmpVersion->Des() ); |
|
204 User::LeaveIfError( SysUtil::GetSWVersion( ptr ) ); |
|
205 |
|
206 _LIT(KVerStrStart,"V "); |
|
207 _LIT(KVerStrEnd,"\n"); |
|
208 |
|
209 TInt pos1 = tmpVersion->Find(KVerStrStart); |
|
210 TInt pos2 = tmpVersion->Find(KVerStrEnd); |
|
211 TInt verlen = ((TDesC)(KVerStrStart)).Length(); |
|
212 |
|
213 // Example version string: |
|
214 // V 10.0.053 |
|
215 // 21-09-07 |
|
216 // RM-179 |
|
217 // (c) Nokia N81 (92.03) |
|
218 |
|
219 // RM-179 is extracted from it |
|
220 |
|
221 if( pos1==KErrNotFound) // Version does not start with "V " |
|
222 { |
|
223 pos1=0; |
|
224 verlen=0; |
|
225 } |
|
226 |
|
227 if( (pos1!=KErrNotFound) |
|
228 && (pos2!=KErrNotFound) |
|
229 && (pos2 > (pos1 + verlen) ) |
|
230 ) |
|
231 { |
|
232 TPtrC ptrSeek(ptr); |
|
233 pos1 = ptrSeek.Find(KVerStrEnd); |
|
234 if(pos1>=0) |
|
235 { |
|
236 ptrSeek.Set(ptrSeek.Mid(pos1+1)); //removes "V 10.0.053" |
|
237 pos1 = ptrSeek.Find(KVerStrEnd); |
|
238 if( pos1 >= 0 ) |
|
239 { |
|
240 ptrSeek.Set(ptrSeek.Mid(pos1+1)); // removes "21-09-07" |
|
241 pos1 = ptrSeek.Find(KVerStrEnd); |
|
242 if( pos1 < 0 ) |
|
243 { |
|
244 ptrSeek.Set(ptrSeek.Mid(1)); |
|
245 aModel.Copy(ptrSeek); |
|
246 } |
|
247 else if( pos1 > 0 ) |
|
248 { |
|
249 ptrSeek.Set(ptrSeek.Mid(1,pos1-1)); |
|
250 aModel.Copy(ptrSeek); |
|
251 } |
|
252 } |
|
253 } |
|
254 } |
|
255 CleanupStack::PopAndDestroy(); |
|
256 } |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CIptvSecureProvisioningParameters::FetchHomeNetworkInfoL |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 void CIptvSecureProvisioningParameters::FetchHomeNetworkInfoL() |
|
263 { |
|
264 // Get home (sim) MCC&MNC info |
|
265 RMobilePhone::TMobilePhoneNetworkInfoV1 info; |
|
266 RMobilePhone::TMobilePhoneNetworkInfoV1Pckg infoPckg( info ); |
|
267 #ifndef __WINS__ |
|
268 TRequestStatus status( KRequestPending ); |
|
269 iPhone.GetHomeNetwork( status, infoPckg ); |
|
270 User::WaitForRequest( status ); |
|
271 User::LeaveIfError( status.Int() ); |
|
272 #else |
|
273 info.iCountryCode.Copy( _L("244") ); |
|
274 info.iNetworkId.Copy( _L("05") ); |
|
275 #endif |
|
276 |
|
277 RMobilePhone::TMobilePhoneNetworkIdentity formattedMnc; |
|
278 FormatMncCodeL( info.iCountryCode, info.iNetworkId, formattedMnc ); |
|
279 SetHomeMncL( formattedMnc ); |
|
280 SetHomeMccL( info.iCountryCode ); |
|
281 } |
|
282 |
|
283 // ----------------------------------------------------------------------------- |
|
284 // CIptvSecureProvisioningParameters::FormatMncCodeL |
|
285 // ----------------------------------------------------------------------------- |
|
286 // |
|
287 void CIptvSecureProvisioningParameters::FormatMncCodeL( |
|
288 const RMobilePhone::TMobilePhoneNetworkCountryCode aMcc, |
|
289 const RMobilePhone::TMobilePhoneNetworkIdentity aUnformattedMnc, |
|
290 RMobilePhone::TMobilePhoneNetworkIdentity& aFormattedMnc ) |
|
291 { |
|
292 RMobilePhone::TMobilePhoneNetworkIdentity formattedMnc; |
|
293 |
|
294 // Check that codes only contain valid characters |
|
295 TInt mncValue(0); |
|
296 TInt mccValue(0); |
|
297 |
|
298 TLex mncParser( aUnformattedMnc ); |
|
299 TInt err = mncParser.Val( mncValue ); |
|
300 if( err != KErrNone ) |
|
301 { |
|
302 User::Leave( KErrCorrupt ); |
|
303 } |
|
304 |
|
305 TLex mccParser( aMcc ); |
|
306 err = mccParser.Val( mccValue ); |
|
307 if( err != KErrNone ) |
|
308 { |
|
309 User::Leave( KErrCorrupt ); |
|
310 } |
|
311 |
|
312 // In N7610 the MNC given by RMobilePhone::GetHomeNetwork is |
|
313 // always three digits |
|
314 // But for example in N6630 the MNC seems to be correctly formatted |
|
315 |
|
316 // The initial value is the given MNC: |
|
317 formattedMnc.Copy( aUnformattedMnc ); |
|
318 |
|
319 // Reformat only if needed |
|
320 if( aUnformattedMnc.Length() == 3 ) |
|
321 { |
|
322 // Assume two digits, exceptions follow |
|
323 formattedMnc.Copy( aUnformattedMnc.Left(2) ); |
|
324 |
|
325 if( aMcc.Compare( _L("302") ) == 0 || |
|
326 aMcc.Compare( _L("346") ) == 0 || |
|
327 aMcc.Compare( _L("348") ) == 0 || |
|
328 aMcc.Compare( _L("356") ) == 0 || |
|
329 aMcc.Compare( _L("365") ) == 0 || |
|
330 aMcc.Compare( _L("376") ) == 0 || |
|
331 aMcc.Compare( _L("467") ) == 0 || |
|
332 aMcc.Compare( _L("732") ) == 0 ) |
|
333 { |
|
334 // MNC should be three digits |
|
335 formattedMnc.Copy( aUnformattedMnc ); |
|
336 } |
|
337 else if( aMcc.Compare( _L("310") ) == 0 ) |
|
338 { |
|
339 // MNC is always three digits in this case |
|
340 // For example: 000, 011, 110, 020, 200, ... |
|
341 formattedMnc.Copy( aUnformattedMnc ); |
|
342 } |
|
343 else if( aMcc.Compare( _L("311") ) == 0 ) |
|
344 { |
|
345 // 3 digit (USA) some exceptions |
|
346 |
|
347 // See previous case for comments |
|
348 formattedMnc.Copy( aUnformattedMnc ); |
|
349 } |
|
350 |
|
351 else if( aMcc.Compare( _L("338") ) == 0 ) |
|
352 { |
|
353 // 2 digit, but 3 digit if 180 (JAM) |
|
354 if( aUnformattedMnc.Compare( _L("180") ) == 0 ) |
|
355 { |
|
356 formattedMnc.Copy( aUnformattedMnc ); |
|
357 } |
|
358 } |
|
359 else if( aMcc.Compare( _L("342") ) == 0 ) |
|
360 { |
|
361 // 2 digit, but 3 digit if larger than 510 |
|
362 if( mncValue >= 510 ) |
|
363 { |
|
364 formattedMnc.Copy( aUnformattedMnc ); |
|
365 } |
|
366 } |
|
367 else if( aMcc.Compare( _L("344") ) == 0 ) |
|
368 { |
|
369 // 2 digit, but 3 digit if larger than 310 |
|
370 if( mncValue >= 310 ) |
|
371 { |
|
372 formattedMnc.Copy( aUnformattedMnc ); |
|
373 } |
|
374 } |
|
375 else if( aMcc.Compare( _L("352") ) == 0 ) |
|
376 { |
|
377 // 2 digit, but 3 digit if smaller than 300 |
|
378 if( mncValue < 300 ) |
|
379 { |
|
380 formattedMnc.Copy( aUnformattedMnc ); |
|
381 } |
|
382 } |
|
383 else if( aMcc.Compare( _L("358") ) == 0 ) |
|
384 { |
|
385 // 2 digit, but 3 digit if smaller than 300 |
|
386 if( mncValue < 300 ) |
|
387 { |
|
388 formattedMnc.Copy( aUnformattedMnc ); |
|
389 } |
|
390 } |
|
391 else if( aMcc.Compare( _L("360") ) == 0 ) |
|
392 { |
|
393 // 2 digit, but 3 digit if 110 |
|
394 if( aUnformattedMnc.Compare( _L("110") ) == 0 ) |
|
395 { |
|
396 formattedMnc.Copy( aUnformattedMnc ); |
|
397 } |
|
398 } |
|
399 else if( aMcc.Compare( _L("362") ) == 0 ) |
|
400 { |
|
401 // 2 digit, but 3 digit if larger than 920 |
|
402 if( mncValue >= 920 ) |
|
403 { |
|
404 formattedMnc.Copy( aUnformattedMnc ); |
|
405 } |
|
406 } |
|
407 else if( aMcc.Compare( _L("366") ) == 0 ) |
|
408 { |
|
409 // 2 digit, but 3 digit if 110 |
|
410 if( aUnformattedMnc.Compare( _L("110") ) == 0 ) |
|
411 { |
|
412 formattedMnc.Copy( aUnformattedMnc ); |
|
413 } |
|
414 } |
|
415 else if( aMcc.Compare( _L("722") ) == 0 ) |
|
416 { |
|
417 // 2 digit, but 3 digit if 310 |
|
418 if( aUnformattedMnc.Compare( _L("310") ) == 0 ) |
|
419 { |
|
420 formattedMnc.Copy( aUnformattedMnc ); |
|
421 } |
|
422 } |
|
423 } |
|
424 aFormattedMnc.Copy( formattedMnc ); |
|
425 } |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // CIptvSecureProvisioningParameters::HomeMccL |
|
429 // ----------------------------------------------------------------------------- |
|
430 // |
|
431 const RMobilePhone::TMobilePhoneNetworkCountryCode CIptvSecureProvisioningParameters::HomeMccL() |
|
432 { |
|
433 RMobilePhone::TMobilePhoneNetworkIdentity mcc; |
|
434 User::LeaveIfError( iRepository->Get( KPnPUtilHomeMcc, mcc ) ); |
|
435 |
|
436 return mcc; |
|
437 } |
|
438 |
|
439 // ----------------------------------------------------------------------------- |
|
440 // CIptvSecureProvisioningParameters::SetHomeMncL |
|
441 // ----------------------------------------------------------------------------- |
|
442 // |
|
443 void CIptvSecureProvisioningParameters::SetHomeMncL( const RMobilePhone::TMobilePhoneNetworkIdentity aMnc ) |
|
444 { |
|
445 User::LeaveIfError( iRepository->Set( KPnPUtilHomeMnc, aMnc ) ); |
|
446 } |
|
447 |
|
448 // ----------------------------------------------------------------------------- |
|
449 // CIptvSecureProvisioningParameters::HomeMncL |
|
450 // ----------------------------------------------------------------------------- |
|
451 // |
|
452 const RMobilePhone::TMobilePhoneNetworkIdentity CIptvSecureProvisioningParameters::HomeMncL() |
|
453 { |
|
454 RMobilePhone::TMobilePhoneNetworkIdentity mnc; |
|
455 User::LeaveIfError( iRepository->Get( KPnPUtilHomeMnc, mnc ) ); |
|
456 return mnc; |
|
457 } |
|
458 |
|
459 // ----------------------------------------------------------------------------- |
|
460 // CIptvSecureProvisioningParameters::SetHomeMccL |
|
461 // ----------------------------------------------------------------------------- |
|
462 // |
|
463 void CIptvSecureProvisioningParameters::SetHomeMccL( const RMobilePhone::TMobilePhoneNetworkCountryCode aMcc ) |
|
464 { |
|
465 User::LeaveIfError( iRepository->Set( KPnPUtilHomeMcc, aMcc ) ); |
|
466 } |
|
467 |
|
468 // ----------------------------------------------------------------------------- |
|
469 // CIptvSecureProvisioningParameters::GetKeyInfoL |
|
470 // ----------------------------------------------------------------------------- |
|
471 // |
|
472 void CIptvSecureProvisioningParameters::GetKeyInfoL( TDes8& aKeyInfo ) |
|
473 { |
|
474 if( aKeyInfo.MaxLength() < KMaxKeyInfoLength ) |
|
475 { |
|
476 User::Leave( KErrArgument ); |
|
477 } |
|
478 // read keyinfo from cenrep |
|
479 TBuf<KMaxKeyInfoLength> buffer; |
|
480 User::LeaveIfError( iRepository->Get( KPnPUtilKeyInfo, buffer) ); |
|
481 aKeyInfo.Copy( buffer ); |
|
482 } |
|
483 |
|
484 // ----------------------------------------------------------------------------- |
|
485 // CIptvSecureProvisioningParameters::CreateNewNonceL |
|
486 // ----------------------------------------------------------------------------- |
|
487 // |
|
488 void CIptvSecureProvisioningParameters::CreateNewNonceL( const TUint /*aTimeOut*/, TDes8& aNonce ) |
|
489 { |
|
490 if( aNonce.MaxLength() < KNonceLength ) |
|
491 { |
|
492 User::Leave( KErrArgument ); |
|
493 } |
|
494 |
|
495 TBuf8<KNonceLength> buffer; |
|
496 |
|
497 TTime time; |
|
498 time.HomeTime(); |
|
499 TInt64 seed = time.Int64(); |
|
500 for( TInt i(0); i < KNonceLength; i++ ) |
|
501 { |
|
502 TChar character( RandomCharacter( seed ) ); |
|
503 buffer.Append( character ); |
|
504 } |
|
505 |
|
506 aNonce.Copy( buffer ); |
|
507 |
|
508 // Encrypt |
|
509 #ifndef __WINS__ |
|
510 iEncryptor->Transform( buffer ); |
|
511 #endif |
|
512 |
|
513 // Save the nonce |
|
514 User::LeaveIfError( iRepository->Set( KPnPUtilNonce, buffer ) ); |
|
515 } |
|
516 |
|
517 // ----------------------------------------------------------------------------- |
|
518 // CIptvSecureProvisioningParameters::RandomCharacter |
|
519 // ----------------------------------------------------------------------------- |
|
520 // |
|
521 TUint CIptvSecureProvisioningParameters::RandomCharacter( TInt64& aSeed ) |
|
522 { |
|
523 // Create random number value for token |
|
524 TInt value = Math::Rand( aSeed ); |
|
525 if( value < 0 ) |
|
526 { |
|
527 value = -value; |
|
528 } |
|
529 value %= 61; // [0,61] |
|
530 value += 48; // [48,109] |
|
531 // split the range to ranges [48,57],[65,90] and [97,122] |
|
532 // that is: the ascii codes for numbers from 0 to 9, |
|
533 // capital alphabets from A to Z and alphabets from a to z |
|
534 if( value > 57 ) |
|
535 { |
|
536 value += 8; // [65,90] |
|
537 if( value > 90 ) |
|
538 { |
|
539 value += 6; // [97,122] |
|
540 } |
|
541 } |
|
542 return value; |
|
543 } |