|
1 /* |
|
2 * Copyright (c) 2003 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 "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: Implementation of the DRM Rights Database |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #include <e32std.h> // RPointerArray |
|
22 #include <e32def.h> // Type definitions |
|
23 #include <hash.h> // MD5 Algorithm |
|
24 // #include <SysUtil.h> // Disk space checking |
|
25 #include <f32file.h> |
|
26 #include <s32strm.h> |
|
27 #include <s32file.h> |
|
28 #include <caf/caf.h> |
|
29 #include <symmetric.h> // AES128CBC |
|
30 #include <dcfrep.h> |
|
31 |
|
32 #ifdef RD_MULTIPLE_DRIVE |
|
33 #include <DriveInfo.h> |
|
34 #endif |
|
35 |
|
36 #include "DRMCommon.h" // DRM Error messages |
|
37 #include "DRMRightsDB.h" |
|
38 #include "DRMRightsData.h" |
|
39 #include "DRMCommonData.h" |
|
40 #include "DRMPermission.h" |
|
41 #include "DRMConstraint.h" |
|
42 #include "DRMRightsCleaner.h" |
|
43 #include "DRMRightsServer.h" |
|
44 #include "DrmKeyStorage.h" |
|
45 #include "utf.h" // charconv, ConvertFromUnicodeToUtf8L |
|
46 #include "drmlog.h" |
|
47 |
|
48 #ifdef RD_DRM_RIGHTS_MANAGER_REMOVAL |
|
49 #include "drmclockclient.h" |
|
50 #endif // RD_DRM_RIGHTS_MANAGER_REMOVAL |
|
51 |
|
52 /* |
|
53 #include "flogger.h" |
|
54 |
|
55 |
|
56 _LIT( KLogDir, "drm"); |
|
57 _LIT( KLogName, "backup.log"); |
|
58 */ |
|
59 |
|
60 // EXTERNAL DATA STRUCTURES |
|
61 |
|
62 // EXTERNAL FUNCTION PROTOTYPES |
|
63 |
|
64 // CONSTANTS |
|
65 |
|
66 // MACROS |
|
67 |
|
68 // LOCAL CONSTANTS AND MACROS |
|
69 #ifdef RD_MULTIPLE_DRIVE |
|
70 // Backup Directory |
|
71 _LIT( KBackupDir, "%c:\\private\\101F51F2\\backup\\" ); |
|
72 #endif |
|
73 |
|
74 |
|
75 _LIT(KJavaExtension, ".jar"); |
|
76 _LIT(KSISExtension, ".sis"); |
|
77 _LIT(KROExtension, ".ro"); |
|
78 _LIT(KXmlExtension, ".xml"); |
|
79 |
|
80 |
|
81 #ifdef RD_MULTIPLE_DRIVE |
|
82 _LIT(KCIDListTempDir, "%c:\\system\\temp\\"); |
|
83 #else |
|
84 _LIT(KCIDListTempDir, "c:\\system\\temp\\"); |
|
85 #endif |
|
86 |
|
87 _LIT(KRODirName, "DomainROs\\"); |
|
88 _LIT(KCorruptionFlagFile, "invalid"); |
|
89 |
|
90 #ifdef __DRM_OMA2 |
|
91 const TInt KMaxUDTDataSize = 256; |
|
92 const TInt KDeviceDataSize = 256; |
|
93 const TInt KDeviceDataBlock = 128; |
|
94 #else |
|
95 const TInt KMaxUDTDataSize = 0; |
|
96 const TInt KDeviceDataSize = 0; |
|
97 const TInt KDeviceDataBlock = 0; |
|
98 #endif |
|
99 const TInt KUdtDataPos = 4 + KDeviceDataSize; |
|
100 |
|
101 |
|
102 const TInt KEncryptionKeySize = 16; |
|
103 const TInt KMaxEncryptionSize = 8192; |
|
104 |
|
105 const TInt KMaxUpdateTime = 3000000; // consider updates to be finished within |
|
106 // three seconds |
|
107 |
|
108 const TUint32 KMaxTIntVal = 2147483647; // 2^31-1 |
|
109 |
|
110 // MODULE DATA STRUCTURES |
|
111 |
|
112 // LOCAL FUNCTION PROTOTYPES |
|
113 LOCAL_C void CleanupData( TAny* aPtr ); |
|
114 LOCAL_C void WriteIntToBlock( TInt aValue, TDes8& aBlock, TInt aOffset ); |
|
115 LOCAL_C void DeleteObject( TAny* aObject ); |
|
116 |
|
117 // FORWARD DECLARATIONS |
|
118 |
|
119 // ============================= LOCAL FUNCTIONS =============================== |
|
120 |
|
121 // ----------------------------------------------------------------------------- |
|
122 // CleanupData |
|
123 // Used to catch errors and delete the file if it's needed |
|
124 // ----------------------------------------------------------------------------- |
|
125 // |
|
126 LOCAL_C void CleanupData( TAny* aPtr ) |
|
127 { |
|
128 CDRMRightsDB* rdb = reinterpret_cast<CDRMRightsDB*>( aPtr ); |
|
129 |
|
130 rdb->CleanUdtData(); |
|
131 } |
|
132 |
|
133 |
|
134 LOCAL_C void WriteIntToBlock( TInt aValue, TDes8& aBlock, TInt aOffset ) |
|
135 { |
|
136 aBlock[aOffset] = (aValue & 0xff000000) >> 24; |
|
137 aBlock[aOffset + 1] = (aValue & 0x00ff0000) >> 16; |
|
138 aBlock[aOffset + 2] = (aValue & 0x0000ff00) >> 8; |
|
139 aBlock[aOffset + 3] = (aValue & 0x000000ff); |
|
140 } |
|
141 |
|
142 // ---------------------------------------------------------------------------- |
|
143 // DeleteObject |
|
144 // Deletes the file by TFileName presented by aHandle |
|
145 // ---------------------------------------------------------------------------- |
|
146 // |
|
147 LOCAL_C void DeleteObject( TAny* aObject ) |
|
148 { |
|
149 __ASSERT_DEBUG( aObject, User::Panic( _L( "DeleteObject" ), KErrArgument ) ); |
|
150 MDrmKeyStorage* object = reinterpret_cast< MDrmKeyStorage* >( aObject ); |
|
151 delete object; |
|
152 object = NULL; |
|
153 } |
|
154 |
|
155 |
|
156 // ============================ MEMBER FUNCTIONS =============================== |
|
157 // ----------------------------------------------------------------------------- |
|
158 // CDRMRightsDB::CDRMRightsDB |
|
159 // C++ default constructor can NOT contain any code, that |
|
160 // might leave. |
|
161 // ----------------------------------------------------------------------------- |
|
162 // |
|
163 CDRMRightsDB::CDRMRightsDB( RFs& aFs ) : |
|
164 iFileServer( aFs ), |
|
165 iImei( NULL ), |
|
166 iLastUpdate( Time::NullTTime() ) |
|
167 { |
|
168 }; |
|
169 |
|
170 |
|
171 // ----------------------------------------------------------------------------- |
|
172 // CDRMRightsDB::ConstructL |
|
173 // Symbian 2nd phase constructor can leave. |
|
174 // ----------------------------------------------------------------------------- |
|
175 // |
|
176 void CDRMRightsDB::ConstructL( const TDesC& aDatabasePath, |
|
177 const TDesC8& aKey, |
|
178 const TDesC& aImei ) |
|
179 { |
|
180 TFileName name; |
|
181 TUint attr; |
|
182 |
|
183 DRMLOG( _L( "RDB starting..." ) ); |
|
184 |
|
185 iDbPath = aDatabasePath.AllocL(); |
|
186 |
|
187 // create an instance of the Hash algorithm class |
|
188 iHasher = CMD5::NewL(); |
|
189 |
|
190 // store the key |
|
191 iKey = aKey.AllocL(); |
|
192 |
|
193 // serial number |
|
194 iImei = aImei.AllocL(); |
|
195 |
|
196 name.Copy( *iDbPath ); |
|
197 name.Append( KCorruptionFlagFile ); |
|
198 |
|
199 if ( iFileServer.Att( name, attr ) == KErrNone ) |
|
200 { |
|
201 iFileServer.RmDir( name ); |
|
202 iFileServer.Delete( name ); |
|
203 DeleteDBL(); |
|
204 } |
|
205 |
|
206 InitializeDatabaseL(); |
|
207 }; |
|
208 |
|
209 // ----------------------------------------------------------------------------- |
|
210 // CDRMRightsDB::NewLC |
|
211 // Two-phased constructor. |
|
212 // ----------------------------------------------------------------------------- |
|
213 // |
|
214 CDRMRightsDB* CDRMRightsDB::NewLC( RFs& aFs, |
|
215 const TDesC& aDatabasePath, |
|
216 const TDesC8& aKey, |
|
217 const TDesC& aImei ) |
|
218 { |
|
219 CDRMRightsDB* self = new( ELeave ) CDRMRightsDB( aFs ); |
|
220 CleanupStack::PushL( self ); |
|
221 self->ConstructL( aDatabasePath, aKey, aImei ); |
|
222 |
|
223 return self; |
|
224 }; |
|
225 |
|
226 // ----------------------------------------------------------------------------- |
|
227 // CDRMRightsDB::NewL |
|
228 // Two-phased constructor. |
|
229 // ----------------------------------------------------------------------------- |
|
230 // |
|
231 CDRMRightsDB* CDRMRightsDB::NewL( RFs& aFs, |
|
232 const TDesC& aDatabaseFile, |
|
233 const TDesC8& aKey, |
|
234 const TDesC& aImei ) |
|
235 { |
|
236 CDRMRightsDB* self = NewLC( aFs, aDatabaseFile, aKey, aImei ); |
|
237 CleanupStack::Pop(); |
|
238 |
|
239 return self; |
|
240 }; |
|
241 |
|
242 // Destructor |
|
243 CDRMRightsDB::~CDRMRightsDB() |
|
244 { |
|
245 if( iHasher ) |
|
246 { |
|
247 delete iHasher; |
|
248 iHasher = NULL; |
|
249 } |
|
250 |
|
251 if( iDbPath ) |
|
252 { |
|
253 delete iDbPath; |
|
254 iDbPath = NULL; |
|
255 } |
|
256 |
|
257 if( iKey ) |
|
258 { |
|
259 delete iKey; |
|
260 iKey = NULL; |
|
261 } |
|
262 |
|
263 if( iImei ) |
|
264 { |
|
265 delete iImei; |
|
266 iImei = NULL; |
|
267 } |
|
268 |
|
269 iMemStream.Close(); |
|
270 |
|
271 DRMLOG( _L( "RDB Closing." ) ); |
|
272 }; |
|
273 |
|
274 |
|
275 // ----------------------------------------------------------------------------- |
|
276 // CDRMRightsDB::GetDBEntryByContentIDL |
|
277 // returns the rights objects connected to aContentID |
|
278 // (other items were commented in a header). |
|
279 // ----------------------------------------------------------------------------- |
|
280 // |
|
281 void CDRMRightsDB::GetDBEntryByContentIDL( |
|
282 const TDesC8& aContentID, |
|
283 RPointerArray<CDRMPermission>& aRightsList) |
|
284 { |
|
285 TFileName path; |
|
286 TInt error = KErrNone; |
|
287 CDRMRightsData* rights = NULL; |
|
288 |
|
289 #ifdef RD_DRM_RIGHTS_MANAGER_REMOVAL |
|
290 TTime time; |
|
291 TBool deleteAllowed = EFalse; |
|
292 TInt timeZone = 0; |
|
293 DRMClock::ESecurityLevel securityLevel; |
|
294 #endif // RD_DRM_RIGHTS_MANAGER_REMOVAL |
|
295 |
|
296 GetRightsFileNameL( aContentID, path); |
|
297 |
|
298 #ifdef RD_DRM_RIGHTS_MANAGER_REMOVAL |
|
299 // Get the secure time: |
|
300 RDRMClockClient client; |
|
301 error = client.Connect(); |
|
302 if( !error ) |
|
303 { |
|
304 client.GetSecureTime( time, timeZone, securityLevel); |
|
305 client.Close(); |
|
306 if( securityLevel == DRMClock::KInsecure ) |
|
307 { |
|
308 time = Time::NullTTime(); |
|
309 } |
|
310 } |
|
311 else |
|
312 { |
|
313 time = Time::NullTTime(); |
|
314 } |
|
315 |
|
316 // Delete expired: |
|
317 TRAP_IGNORE( deleteAllowed = DeleteExpiredL( path, time ) ); |
|
318 |
|
319 // Check if it's possible to delete the file as well |
|
320 if( deleteAllowed ) |
|
321 { |
|
322 iFileServer.Delete( path ); |
|
323 } |
|
324 |
|
325 error = KErrNone; |
|
326 #endif // RD_DRM_RIGHTS_MANAGER_REMOVAL |
|
327 |
|
328 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
329 if( rights ) |
|
330 { |
|
331 CleanupStack::PushL( rights ); |
|
332 } |
|
333 else |
|
334 { |
|
335 if( error == KErrNotFound ) |
|
336 { |
|
337 User::Leave( KErrCANoRights ); |
|
338 } |
|
339 User::Leave( error ); |
|
340 } |
|
341 |
|
342 rights->FetchAllPermissionsL( aRightsList ); |
|
343 |
|
344 CleanupStack::PopAndDestroy(); // rights |
|
345 }; |
|
346 |
|
347 // ----------------------------------------------------------------------------- |
|
348 // CDRMRightsDB::GetDBEntryByContentIDL |
|
349 // returns the rights object connected to aContentID and aUniqueID |
|
350 // (other items were commented in a header). |
|
351 // ----------------------------------------------------------------------------- |
|
352 // |
|
353 CDRMPermission* CDRMRightsDB::GetDBEntryByContentIDL( |
|
354 const TDesC8& aContentID, |
|
355 const TDRMUniqueID aUniqueID ) |
|
356 { |
|
357 TFileName path; |
|
358 TInt error = KErrNone; |
|
359 CDRMRightsData* rights = NULL; |
|
360 CDRMPermission* ro = NULL; |
|
361 |
|
362 if( aUniqueID > KMaxTIntVal ) |
|
363 { |
|
364 User::Leave( KErrArgument ); |
|
365 } |
|
366 |
|
367 GetRightsFileNameL( aContentID, path); |
|
368 |
|
369 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
370 if( rights ) |
|
371 { |
|
372 CleanupStack::PushL( rights ); |
|
373 } |
|
374 else |
|
375 { |
|
376 if( error == KErrNotFound ) |
|
377 { |
|
378 User::Leave( KErrCANoRights ); |
|
379 } |
|
380 User::Leave( error ); |
|
381 } |
|
382 |
|
383 ro = CDRMPermission::NewLC(); |
|
384 |
|
385 rights->FetchPermissionL( *ro, aUniqueID ); |
|
386 |
|
387 CleanupStack::Pop(); // ro |
|
388 CleanupStack::PopAndDestroy(); // rights |
|
389 return ro; |
|
390 }; |
|
391 |
|
392 |
|
393 // ----------------------------------------------------------------------------- |
|
394 // CDRMRightsDB::AddDBEntryL |
|
395 // adds a new rights object into the database and uses the given aUniqueID if |
|
396 // possible, if not it generates a new one |
|
397 // (other items were commented in a header). |
|
398 // ----------------------------------------------------------------------------- |
|
399 // |
|
400 void CDRMRightsDB::AddDBEntryL( const TDesC8& aContentID, |
|
401 CDRMPermission& aRightsObject, |
|
402 const TDesC8& aEncryptionKey, |
|
403 TDRMUniqueID& aUniqueID ) |
|
404 { |
|
405 TFileName path; |
|
406 TInt error = KErrNone; |
|
407 CDRMRightsData* rights = NULL; |
|
408 TBuf8<16> nullDesc; |
|
409 TBuf<16> nullDesc2; |
|
410 HBufC8* oldKey = NULL; |
|
411 |
|
412 DRMLOG( _L( "CDRMRightsDB::AddDBEntryL ->" ) ); |
|
413 |
|
414 // Indicate that the DB is updated |
|
415 iLastUpdate.HomeTime(); |
|
416 |
|
417 // the key can either be empty or it can be 16 characters: |
|
418 if( !( aEncryptionKey.Length() == KEncryptionKeySize || aEncryptionKey.Length() == 0 ) ) |
|
419 { |
|
420 User::Leave(KErrArgument); |
|
421 } |
|
422 |
|
423 TBuf8<16> keyStore = aEncryptionKey; |
|
424 // TBuf8<16> authStore = aAuthenticationSeed |
|
425 |
|
426 // Encrypt the key |
|
427 ModifyKey( keyStore ); |
|
428 |
|
429 // Modify also the authentication seed |
|
430 // ModifyKey( authStore ) |
|
431 |
|
432 GetRightsFileNameL( aContentID, path); |
|
433 |
|
434 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
435 if( rights ) |
|
436 { |
|
437 CleanupStack::PushL( rights ); |
|
438 |
|
439 |
|
440 // Check that the keys match, if not leave with KErrArgument |
|
441 oldKey = rights->GetKeyL(); |
|
442 if ( oldKey != NULL ) |
|
443 { |
|
444 CleanupStack::PushL( oldKey ); |
|
445 if( oldKey->Compare(keyStore) ) |
|
446 { |
|
447 User::Leave(KErrArgument); |
|
448 } |
|
449 CleanupStack::PopAndDestroy( oldKey ); |
|
450 } |
|
451 } |
|
452 |
|
453 if( error == KErrNotFound ) |
|
454 { |
|
455 // This would need the other info if it was available: |
|
456 CDRMCommonData* data = CDRMCommonData::NewL( aContentID, nullDesc, aRightsObject.iRiId, nullDesc2, nullDesc ); |
|
457 |
|
458 rights = CDRMRightsData::NewLC( data, keyStore, path, iFileServer ); |
|
459 } |
|
460 else |
|
461 { |
|
462 User::LeaveIfError( error ); |
|
463 } |
|
464 |
|
465 // Store the RO: |
|
466 rights->StoreNewPermissionL( aRightsObject, aUniqueID ); |
|
467 |
|
468 CleanupStack::PopAndDestroy(); // rights |
|
469 |
|
470 DRMLOG( _L( "CDRMRightsDB::AddDBEntryL <-" ) ); |
|
471 }; |
|
472 |
|
473 // ----------------------------------------------------------------------------- |
|
474 // CDRMRightsDB::DeleteDBEntryL |
|
475 // deletes the rights object connected to aContentID and aUniqueID |
|
476 // (other items were commented in a header). |
|
477 // ----------------------------------------------------------------------------- |
|
478 // |
|
479 void CDRMRightsDB::DeleteDBEntryL( const TDesC8& aContentID, |
|
480 const TDRMUniqueID aUniqueID ) |
|
481 { |
|
482 TFileName path; |
|
483 TInt error = KErrNone; |
|
484 CDRMRightsData* rights = NULL; |
|
485 |
|
486 DRMLOG( _L( "CDRMRightsDB::DeleteDBEntryL ->" ) ); |
|
487 |
|
488 if( aUniqueID > KMaxTIntVal ) |
|
489 { |
|
490 User::Leave( KErrArgument ); |
|
491 } |
|
492 |
|
493 GetRightsFileNameL( aContentID, path); |
|
494 |
|
495 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
496 if( rights ) |
|
497 { |
|
498 CleanupStack::PushL( rights ); |
|
499 } |
|
500 else |
|
501 { |
|
502 if( error == KErrNotFound ) |
|
503 { |
|
504 User::Leave( DRMCommon::ENoRights ); |
|
505 } |
|
506 User::Leave( error ); |
|
507 } |
|
508 |
|
509 // Indicate that the DB is updated |
|
510 iLastUpdate.HomeTime(); |
|
511 rights->DeletePermissionL( aUniqueID ); |
|
512 |
|
513 CleanupStack::PopAndDestroy(); // rights |
|
514 |
|
515 // Check if the file can be deleted: |
|
516 CheckCleanup( path ); |
|
517 |
|
518 DRMLOG( _L( "CDRMRightsDB::DeleteDBEntryL <-" ) ); |
|
519 }; |
|
520 |
|
521 // ----------------------------------------------------------------------------- |
|
522 // CDRMRightsDB::DeleteDBEntryL |
|
523 // deletes all rights object connected to aContenID |
|
524 // (other items were commented in a header). |
|
525 // ----------------------------------------------------------------------------- |
|
526 // |
|
527 void CDRMRightsDB::DeleteDBEntryL( const TDesC8& aContentID ) |
|
528 { |
|
529 TFileName path; |
|
530 TInt error = KErrNone; |
|
531 CDRMRightsData* rights = NULL; |
|
532 |
|
533 DRMLOG( _L( "CDRMRightsDB::DeleteDBEntryL (2) ->" ) ); |
|
534 |
|
535 GetRightsFileNameL( aContentID, path); |
|
536 |
|
537 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
538 if( rights ) |
|
539 { |
|
540 CleanupStack::PushL( rights ); |
|
541 } |
|
542 else |
|
543 { |
|
544 if( error == KErrNotFound ) |
|
545 { |
|
546 User::Leave( DRMCommon::ENoRights ); |
|
547 } |
|
548 User::Leave( error ); |
|
549 } |
|
550 |
|
551 // Indicate that the DB is updated |
|
552 iLastUpdate.HomeTime(); |
|
553 rights->DeleteAllPermissionsL(); |
|
554 |
|
555 CleanupStack::PopAndDestroy(); // rights |
|
556 |
|
557 // Check if the file can be deleted: |
|
558 CheckCleanup( path ); |
|
559 |
|
560 DRMLOG( _L( "CDRMRightsDB::DeleteDBEntryL (2) <-" ) ); |
|
561 }; |
|
562 |
|
563 |
|
564 // ----------------------------------------------------------------------------- |
|
565 // CDRMRightsDB::UpdateDBEntryL |
|
566 // updates the requested rights object to the given rights object |
|
567 // (other items were commented in a header). |
|
568 // ----------------------------------------------------------------------------- |
|
569 // |
|
570 void CDRMRightsDB::UpdateDBEntryL( const TDesC8& aContentID, |
|
571 const CDRMPermission& aRightsObject ) |
|
572 { |
|
573 TFileName path; |
|
574 TInt error = KErrNone; |
|
575 CDRMRightsData* rights = NULL; |
|
576 |
|
577 DRMLOG( _L( "CDRMRightsDB::UpdateDBEntryL ->" ) ); |
|
578 |
|
579 // Should never occur: |
|
580 if( aRightsObject.iUniqueID > KMaxTIntVal ) |
|
581 { |
|
582 User::Leave( KErrArgument ); |
|
583 } |
|
584 |
|
585 |
|
586 GetRightsFileNameL( aContentID, path); |
|
587 |
|
588 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
589 if( rights ) |
|
590 { |
|
591 CleanupStack::PushL( rights ); |
|
592 } |
|
593 else |
|
594 { |
|
595 if( error == KErrNotFound ) |
|
596 { |
|
597 User::Leave( DRMCommon::ENoRights ); |
|
598 } |
|
599 User::Leave( error ); |
|
600 } |
|
601 |
|
602 // Indicate that the DB is updated |
|
603 iLastUpdate.HomeTime(); |
|
604 rights->UpdatePermissionL( aRightsObject ); |
|
605 |
|
606 CleanupStack::PopAndDestroy(); // rights |
|
607 |
|
608 DRMLOG( _L( "CDRMRightsDB::UpdateDBEntryL <-" ) ); |
|
609 }; |
|
610 |
|
611 // ----------------------------------------------------------------------------- |
|
612 // CDRMRightsDB::ExportContentIDListL |
|
613 // writes each unique content id to the requested file |
|
614 // (other items were commented in a header). |
|
615 // ----------------------------------------------------------------------------- |
|
616 // |
|
617 void CDRMRightsDB::ExportContentIDListL( TFileName& aTempFile ) |
|
618 { |
|
619 __UHEAP_MARK; |
|
620 RFileWriteStream stream; |
|
621 |
|
622 |
|
623 #ifndef RD_MULTIPLE_DRIVE |
|
624 |
|
625 User::LeaveIfError( stream.Temp( iFileServer, |
|
626 KCIDListTempDir, |
|
627 aTempFile, |
|
628 EFileWrite ) ); |
|
629 |
|
630 #else //RD_MULTIPLE_DRIVE |
|
631 |
|
632 TInt driveNumber( -1 ); |
|
633 TChar driveLetter; |
|
634 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
635 iFileServer.DriveToChar( driveNumber, driveLetter ); |
|
636 |
|
637 TFileName cidTemp; |
|
638 cidTemp.Format( KCIDListTempDir, (TUint)driveLetter ); |
|
639 |
|
640 User::LeaveIfError( stream.Temp( iFileServer, |
|
641 cidTemp, |
|
642 aTempFile, |
|
643 EFileWrite ) ); |
|
644 |
|
645 #endif |
|
646 |
|
647 CleanupClosePushL( stream ); |
|
648 |
|
649 for (TInt i = 0; i < 16; i++) |
|
650 { |
|
651 CDir* files = NULL; |
|
652 |
|
653 TFileName path = *iDbPath; |
|
654 |
|
655 path.Append(i < 10 ? i + '0' : i + 'a' - 10); |
|
656 path.Append('\\'); |
|
657 |
|
658 if ( iFileServer.GetDir(path, KEntryAttDir, ESortNone, files) == KErrNone ) |
|
659 { |
|
660 TInt j; |
|
661 |
|
662 CleanupStack::PushL( files ); |
|
663 |
|
664 for (j = 0; j < files->Count(); j++) |
|
665 { |
|
666 TFileName tempPath( path ); |
|
667 |
|
668 tempPath.Append((*files)[j].iName); |
|
669 |
|
670 TInt error = KErrNone; |
|
671 CDRMRightsData* rights = NULL; |
|
672 |
|
673 TRAP( error, rights = CDRMRightsData::OpenL( tempPath, iFileServer ) ); |
|
674 if( rights ) |
|
675 { |
|
676 CleanupStack::PushL( rights ); |
|
677 } |
|
678 else |
|
679 { |
|
680 if( error != KErrNotFound ) |
|
681 { |
|
682 User::Leave( error ); |
|
683 } |
|
684 continue; |
|
685 } |
|
686 |
|
687 const CDRMCommonData* data = rights->GetCommonDataL(); |
|
688 stream.WriteUint16L( data->ContentID().Length() ); |
|
689 stream.WriteL( data->ContentID() ); |
|
690 |
|
691 CleanupStack::PopAndDestroy(); // rights |
|
692 } |
|
693 |
|
694 CleanupStack::PopAndDestroy(); // files |
|
695 } |
|
696 } |
|
697 |
|
698 stream.WriteUint16L(0); |
|
699 |
|
700 CleanupStack::PopAndDestroy(); // stream |
|
701 |
|
702 __UHEAP_MARKEND; |
|
703 }; |
|
704 |
|
705 // ----------------------------------------------------------------------------- |
|
706 // CDRMRightsDB::BackupDBL |
|
707 // creates a backupfile of the current rights database and encrypts it using the |
|
708 // database encryption key |
|
709 // (other items were commented in a header). |
|
710 // ----------------------------------------------------------------------------- |
|
711 // |
|
712 /* |
|
713 void CDRMRightsDB::BackupDBL( const TDesC& aWTFile, |
|
714 const TDesC8& aEncryptionKey ) |
|
715 { |
|
716 }; |
|
717 */ |
|
718 // ----------------------------------------------------------------------------- |
|
719 // CDRMRightsDB::MergeDBL |
|
720 // merges the backup database into the current database and deletes the backup |
|
721 // file afterwards, any rights objects with counter base rights or non activated |
|
722 // intervals are not inserted. If an equal combination of content id and unique |
|
723 // id is found that object is not restored |
|
724 // (other items were commented in a header). |
|
725 // ----------------------------------------------------------------------------- |
|
726 // |
|
727 /* |
|
728 void CDRMRightsDB::MergeDBL() |
|
729 { |
|
730 }; |
|
731 */ |
|
732 |
|
733 |
|
734 // ----------------------------------------------------------------------------- |
|
735 // CDRMRightsDB::GetDecryptionKeyL |
|
736 // returns a pointer to the decryption key of the requested content id |
|
737 // (other items were commented in a header). |
|
738 // ----------------------------------------------------------------------------- |
|
739 // |
|
740 HBufC8* CDRMRightsDB::GetDecryptionKeyL( |
|
741 const TDesC8& aContentID) |
|
742 { |
|
743 |
|
744 TFileName path; |
|
745 TInt error = KErrNone; |
|
746 HBufC8* key = NULL; |
|
747 CDRMRightsData* rights = NULL; |
|
748 |
|
749 GetRightsFileNameL( aContentID, path); |
|
750 |
|
751 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
752 if( rights ) |
|
753 { |
|
754 CleanupStack::PushL( rights ); |
|
755 } |
|
756 else |
|
757 { |
|
758 if( error == KErrNotFound ) |
|
759 { |
|
760 User::Leave( DRMCommon::ENoRights ); |
|
761 } |
|
762 User::Leave( error ); |
|
763 } |
|
764 |
|
765 key = rights->GetKeyL(); |
|
766 |
|
767 // Decrypt the key |
|
768 ModifyKey( *key ); |
|
769 |
|
770 CleanupStack::PopAndDestroy(); // rights |
|
771 |
|
772 return key; |
|
773 }; |
|
774 |
|
775 // ----------------------------------------------------------------------------- |
|
776 // CDRMRightsDB::DeleteDBL |
|
777 // deletes the rights database and creates a new empty one in it's place |
|
778 // (other items were commented in a header). |
|
779 // ----------------------------------------------------------------------------- |
|
780 // |
|
781 void CDRMRightsDB::DeleteDBL( void ) |
|
782 { |
|
783 DRMLOG( _L( "CDRMRightsDB::DeleteDBL ->" ) ); |
|
784 |
|
785 // Indicate that the DB is updated |
|
786 iLastUpdate.HomeTime(); |
|
787 |
|
788 CFileMan* fileMan = CFileMan::NewL(iFileServer); |
|
789 fileMan->RmDir(*iDbPath); |
|
790 delete fileMan; |
|
791 |
|
792 InitializeDatabaseL(); |
|
793 |
|
794 DRMLOG( _L( "CDRMRightsDB::DeleteDBL <-" ) ); |
|
795 }; |
|
796 |
|
797 |
|
798 // ----------------------------------------------------------------------------- |
|
799 // CDRMRightsDB::GetAmountOfRightsObjectsL |
|
800 // returns the amount of different content id's in the database |
|
801 // (other items were commented in a header). |
|
802 // ----------------------------------------------------------------------------- |
|
803 // |
|
804 TInt32 CDRMRightsDB::GetAmountOfRightsObjectsL() |
|
805 { |
|
806 TInt32 amount( 0 ); |
|
807 |
|
808 for (TInt i = 0; i < 16; i++) |
|
809 { |
|
810 CDir* files = NULL; |
|
811 |
|
812 TFileName path = *iDbPath; |
|
813 |
|
814 path.Append(i < 10 ? i + '0' : i + 'a' - 10); |
|
815 path.Append('\\'); |
|
816 |
|
817 User::LeaveIfError( |
|
818 iFileServer.GetDir(path, KEntryAttDir, ESortNone, files) ); |
|
819 |
|
820 #ifdef _DEBUG |
|
821 if ( !files ) |
|
822 { |
|
823 DRMLOG( _L( "CDRMRightsDB::GetAmountOfRightsObject: GetDir returned NULL pointer!" ) ); |
|
824 User::Leave( KErrGeneral ); |
|
825 } |
|
826 #endif |
|
827 |
|
828 amount += files->Count(); |
|
829 delete files; |
|
830 } |
|
831 |
|
832 return amount; |
|
833 }; |
|
834 |
|
835 |
|
836 |
|
837 // ----------------------------------------------------------------------------- |
|
838 // CDRMRightsDB::AddDomainROL |
|
839 // ----------------------------------------------------------------------------- |
|
840 // |
|
841 void CDRMRightsDB::AddDomainROL( const TDesC8& aRoId, const TDesC8& aXmlData ) |
|
842 { |
|
843 RFile file; |
|
844 TFileName path; |
|
845 TPtr8 numWrite(NULL,0); |
|
846 TInt num = 0; |
|
847 |
|
848 DRMLOG( _L( "CDRMRightsDB::AddDomainROL ->" ) ); |
|
849 |
|
850 // Indicate that the DB is updated |
|
851 iLastUpdate.HomeTime(); |
|
852 |
|
853 // Get the size and if it is zero, leave |
|
854 num = aXmlData.Size(); |
|
855 if( !num ) |
|
856 { |
|
857 User::Leave(KErrArgument); |
|
858 } |
|
859 |
|
860 // Get the filename |
|
861 GetXMLFileNameL( aRoId, path ); |
|
862 |
|
863 // Replace whatever is in there |
|
864 User::LeaveIfError( file.Replace( iFileServer, path, EFileWrite ) ); |
|
865 CleanupClosePushL( file ); |
|
866 |
|
867 // write the size of the data |
|
868 numWrite.Set(reinterpret_cast<TUint8*>(&num), sizeof(TInt), sizeof(TInt)); |
|
869 |
|
870 // needs a check if there is enough diskspace for sizeof(TInt) + num bytes |
|
871 |
|
872 User::LeaveIfError( file.Write( numWrite ) ); |
|
873 |
|
874 // write the data |
|
875 User::LeaveIfError( file.Write( aXmlData ) ); |
|
876 |
|
877 CleanupStack::PopAndDestroy(); // file |
|
878 |
|
879 DRMLOG( _L( "CDRMRightsDB::AddDomainROL <-" ) ); |
|
880 }; |
|
881 |
|
882 // ----------------------------------------------------------------------------- |
|
883 // CDRMRightsDB::GetDomainROL |
|
884 // ----------------------------------------------------------------------------- |
|
885 // |
|
886 HBufC8* CDRMRightsDB::GetDomainROL( const TDesC8& aRoId ) |
|
887 { |
|
888 RFile file; |
|
889 TFileName path; |
|
890 TPtr8 inRead(NULL,0); |
|
891 TInt num = 0; |
|
892 HBufC8* data = NULL; |
|
893 |
|
894 // Get the filename |
|
895 GetXMLFileNameL( aRoId, path ); |
|
896 |
|
897 // Replace whatever is in there |
|
898 User::LeaveIfError( file.Open( iFileServer, path, EFileRead ) ); |
|
899 CleanupClosePushL( file ); |
|
900 |
|
901 // read the size of the data |
|
902 inRead.Set(reinterpret_cast<TUint8*>(&num), 0, sizeof(TInt)); |
|
903 User::LeaveIfError( file.Read( inRead, sizeof(TInt) ) ); |
|
904 |
|
905 if( num <= 0 ) |
|
906 { |
|
907 User::Leave(KErrCorrupt); |
|
908 } |
|
909 |
|
910 data = HBufC8::NewMaxLC( num ); |
|
911 |
|
912 // read the data |
|
913 inRead.Set( const_cast<TUint8*>( data->Ptr() ), 0, num ); |
|
914 User::LeaveIfError( file.Read( inRead, num ) ); |
|
915 |
|
916 CleanupStack::Pop(); // data |
|
917 CleanupStack::PopAndDestroy(); // Close the file |
|
918 return data; |
|
919 }; |
|
920 |
|
921 // ----------------------------------------------------------------------------- |
|
922 // CDRMRightsDB::DeleteDomainROL |
|
923 // ----------------------------------------------------------------------------- |
|
924 // |
|
925 void CDRMRightsDB::DeleteDomainROL( const TDesC8& aRoId ) |
|
926 { |
|
927 TFileName path; |
|
928 |
|
929 DRMLOG( _L( "CDRMRightsDB::DeleteDomainROL ->" ) ); |
|
930 |
|
931 // Indicate that the DB is updated |
|
932 iLastUpdate.HomeTime(); |
|
933 |
|
934 // Get the filename |
|
935 GetXMLFileNameL( aRoId, path ); |
|
936 |
|
937 User::LeaveIfError( iFileServer.Delete( path ) ); |
|
938 |
|
939 DRMLOG( _L( "CDRMRightsDB::DeleteDomainROL <-" ) ); |
|
940 }; |
|
941 |
|
942 // ----------------------------------------------------------------------------- |
|
943 // CDRMRightsDB::DeleteExpiredPermissionsL |
|
944 // ----------------------------------------------------------------------------- |
|
945 // |
|
946 CDRMRightsCleaner* CDRMRightsDB::DeleteExpiredPermissionsL( const TTime& aTime, |
|
947 TRequestStatus& aStatus ) |
|
948 { |
|
949 |
|
950 |
|
951 CDRMRightsCleaner* cleaner = CDRMRightsCleaner::NewL( iFileServer, |
|
952 const_cast<CDRMRightsDB*>(this), |
|
953 aStatus, |
|
954 *iDbPath, |
|
955 aTime); |
|
956 return cleaner; |
|
957 } |
|
958 |
|
959 // ----------------------------------------------------------------------------- |
|
960 // CDRMRightsDB::NameContentL |
|
961 // ----------------------------------------------------------------------------- |
|
962 // |
|
963 void CDRMRightsDB::NameContentL( const TDesC8& aContentId, |
|
964 const TDesC& aName ) |
|
965 { |
|
966 TFileName path; |
|
967 TInt error = KErrNone; |
|
968 CDRMRightsData* rights = NULL; |
|
969 CDRMCommonData* data = NULL; |
|
970 |
|
971 GetRightsFileNameL( aContentId, path); |
|
972 |
|
973 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
974 if( rights ) |
|
975 { |
|
976 CleanupStack::PushL( rights ); |
|
977 } |
|
978 else |
|
979 { |
|
980 User::Leave( error ); |
|
981 } |
|
982 |
|
983 data = const_cast<CDRMCommonData*>(rights->GetCommonDataL()); |
|
984 |
|
985 data->SetContentNameL( aName ); |
|
986 |
|
987 rights->UpdateCommonDataL( data ); |
|
988 |
|
989 CleanupStack::PopAndDestroy(); // rights |
|
990 }; |
|
991 |
|
992 |
|
993 // ----------------------------------------------------------------------------- |
|
994 // CDRMRightsDB::ContentNameL |
|
995 // ----------------------------------------------------------------------------- |
|
996 // |
|
997 HBufC* CDRMRightsDB::ContentNameLC( const TDesC8& aContentId ) |
|
998 { |
|
999 TFileName path; |
|
1000 CDRMRightsData* rights( NULL ); |
|
1001 HBufC* name( NULL ); |
|
1002 |
|
1003 GetRightsFileNameL( aContentId, path ); |
|
1004 |
|
1005 rights = CDRMRightsData::OpenL( path, iFileServer ); |
|
1006 CleanupStack::PushL( rights ); |
|
1007 |
|
1008 name = const_cast< CDRMCommonData* >( rights->GetCommonDataL() ) |
|
1009 ->ContentName().AllocL(); |
|
1010 |
|
1011 CleanupStack::PopAndDestroy(); // rights |
|
1012 CleanupStack::PushL( name ); |
|
1013 |
|
1014 return name; |
|
1015 } |
|
1016 |
|
1017 // ----------------------------------------------------------------------------- |
|
1018 // CDRMRightsDB::DeleteExpiredL |
|
1019 // ----------------------------------------------------------------------------- |
|
1020 // |
|
1021 TBool CDRMRightsDB::DeleteExpiredL( const TFileName& aFileName, |
|
1022 const TTime& aTime ) |
|
1023 { |
|
1024 CDRMRightsData* rights = NULL; |
|
1025 TInt amountLeft = -1; |
|
1026 TBool retVal = EFalse; |
|
1027 TBool parents = EFalse; |
|
1028 |
|
1029 DRMLOG( _L( "CDRMRightsDB::DeleteExpiredL ->" ) ); |
|
1030 |
|
1031 // Indicate that the DB is updated |
|
1032 iLastUpdate.HomeTime(); |
|
1033 |
|
1034 // Open the rights file |
|
1035 DRMLOG( _L("Opening the file")); |
|
1036 rights = CDRMRightsData::OpenLC( aFileName, iFileServer ); |
|
1037 |
|
1038 DRMLOG( _L("Running Delete")); |
|
1039 amountLeft = rights->DeleteExpiredPermissionsL( aTime, parents ); |
|
1040 |
|
1041 DRMLOG2( _L("Checking for left RO:s %d"), amountLeft ); |
|
1042 |
|
1043 // See if any permissions are left if not check if the whole file |
|
1044 // can be proposed to be deleted or not, Java files require uninstallation |
|
1045 // so those need to be checked |
|
1046 if( !amountLeft && !parents ) |
|
1047 { |
|
1048 // get the common data |
|
1049 const CDRMCommonData* common= rights->GetCommonDataL(); |
|
1050 |
|
1051 // If it is a java file, dont allow deletion |
|
1052 if( !common->ContentName().Right(4).CompareF(KJavaExtension) ) |
|
1053 { |
|
1054 DRMLOG( _L("Is java file, do not delete")); |
|
1055 retVal = EFalse; |
|
1056 } |
|
1057 else if( !common->ContentName().Right(4).CompareF(KSISExtension) ) |
|
1058 { |
|
1059 DRMLOG( _L("Is an installation package, do not delete")); |
|
1060 retVal = EFalse; |
|
1061 } |
|
1062 else |
|
1063 { |
|
1064 retVal = ETrue; |
|
1065 } |
|
1066 } |
|
1067 CleanupStack::PopAndDestroy(); // rights |
|
1068 |
|
1069 DRMLOG( _L( "CDRMRightsDB::DeleteExpiredL <-" ) ); |
|
1070 |
|
1071 return retVal; |
|
1072 } |
|
1073 |
|
1074 |
|
1075 // ----------------------------------------------------------------------------- |
|
1076 // CDRMRightsDB::GetUdtDataLC |
|
1077 // ----------------------------------------------------------------------------- |
|
1078 // |
|
1079 HBufC8* CDRMRightsDB::GetUdtDataLC() |
|
1080 { |
|
1081 #ifdef __DRM_OMA2 |
|
1082 HBufC8* udtData = HBufC8::NewMaxLC( KMaxUDTDataSize ); |
|
1083 TFileName backupFile; |
|
1084 RFile input; |
|
1085 TInt pos = KUdtDataPos; |
|
1086 TPtr8 inRead( udtData->Des() ); |
|
1087 |
|
1088 #ifndef RD_MULTIPLE_DRIVE |
|
1089 |
|
1090 backupFile.Copy( KBackupDirectory ); |
|
1091 |
|
1092 #else //RD_MULTIPLE_DRIVE |
|
1093 |
|
1094 TInt driveNumber( -1 ); |
|
1095 TChar driveLetter; |
|
1096 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
1097 iFileServer.DriveToChar( driveNumber, driveLetter ); |
|
1098 |
|
1099 TFileName backupDir; |
|
1100 backupDir.Format( KBackupDir, (TUint)driveLetter ); |
|
1101 |
|
1102 backupFile.Copy( backupDir ); |
|
1103 |
|
1104 #endif |
|
1105 |
|
1106 backupFile.Append( KRightsDbBackupFile ); |
|
1107 |
|
1108 // Open the udt file |
|
1109 User::LeaveIfError( input.Open( iFileServer, backupFile, EFileRead ) ); |
|
1110 CleanupClosePushL( input ); |
|
1111 |
|
1112 // Find the correct spot in the file |
|
1113 User::LeaveIfError( input.Seek( ESeekStart, pos ) ); |
|
1114 |
|
1115 // Read the data from the file |
|
1116 User::LeaveIfError( input.Read( inRead, KMaxUDTDataSize ) ); |
|
1117 |
|
1118 CleanupStack::PopAndDestroy(); // input |
|
1119 return udtData; |
|
1120 #else |
|
1121 User::Leave(KErrNotSupported); |
|
1122 return NULL; |
|
1123 #endif |
|
1124 }; |
|
1125 |
|
1126 // ----------------------------------------------------------------------------- |
|
1127 // CDRMRightsDB::InitiateUdtL |
|
1128 // ----------------------------------------------------------------------------- |
|
1129 // |
|
1130 #ifdef __DRM_OMA2 |
|
1131 void CDRMRightsDB::InitiateUdtL( const TDesC8& aKey ) |
|
1132 #else |
|
1133 void CDRMRightsDB::InitiateUdtL( const TDesC8& ) |
|
1134 #endif // __DRM_OMA2 |
|
1135 { |
|
1136 #ifdef __DRM_OMA2 |
|
1137 TFileName backupFile; |
|
1138 RFile input; |
|
1139 HBufC8* keyData = NULL; |
|
1140 |
|
1141 MDrmKeyStorage* storage = DrmKeyStorageNewL(); |
|
1142 |
|
1143 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
1144 CleanupStack::PushL(storageCleanup); |
|
1145 |
|
1146 keyData = storage->RsaDecryptL( aKey ); |
|
1147 |
|
1148 CleanupStack::PopAndDestroy();// storageCleanup |
|
1149 CleanupStack::PushL( keyData ); |
|
1150 |
|
1151 #ifndef RD_MULTIPLE_DRIVE |
|
1152 |
|
1153 backupFile.Copy( KBackupDirectory ); |
|
1154 |
|
1155 #else //RD_MULTIPLE_DRIVE |
|
1156 |
|
1157 TInt driveNumber( -1 ); |
|
1158 TChar driveLetter; |
|
1159 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
1160 iFileServer.DriveToChar( driveNumber, driveLetter ); |
|
1161 |
|
1162 TFileName backupDir; |
|
1163 backupDir.Format( KBackupDir, (TUint)driveLetter ); |
|
1164 |
|
1165 backupFile.Copy( backupDir ); |
|
1166 |
|
1167 #endif |
|
1168 |
|
1169 backupFile.Append( KRightsDbBackupFile ); |
|
1170 |
|
1171 // Open the udt file |
|
1172 User::LeaveIfError( input.Open( iFileServer, backupFile, EFileRead ) ); |
|
1173 CleanupClosePushL( input ); |
|
1174 |
|
1175 // Add the cleanup item to the cleanup stack |
|
1176 TCleanupItem resetAndDestroy( CleanupData, reinterpret_cast<TAny*>(this) ); |
|
1177 CleanupStack::PushL( resetAndDestroy ); |
|
1178 |
|
1179 // DEBUG DEBUG DEBUG: ignore the error |
|
1180 TRAPD( error, RestoreContentFromFileL( input, |
|
1181 keyData->Right(KEncryptionKeySize), |
|
1182 KDRMUDTBackup ) ); |
|
1183 if( error ) |
|
1184 { |
|
1185 // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("InitiateUdtL: Restore failed\n\r")); |
|
1186 User::Leave(error); |
|
1187 } |
|
1188 CleanupStack::PopAndDestroy( 3 ); // input, cleanup item, keyData |
|
1189 #else |
|
1190 User::Leave(KErrNotSupported); |
|
1191 #endif // __DRM_OMA2 |
|
1192 }; |
|
1193 |
|
1194 |
|
1195 // ----------------------------------------------------------------------------- |
|
1196 // CDRMRightsDB::GetContentIDListL |
|
1197 // ----------------------------------------------------------------------------- |
|
1198 // |
|
1199 void CDRMRightsDB::GetContentIDListL( RPointerArray<HBufC8>& aArray ) |
|
1200 { |
|
1201 HBufC8* contentId = NULL; |
|
1202 |
|
1203 for (TInt i = 0; i < 16; i++) |
|
1204 { |
|
1205 CDir* files = NULL; |
|
1206 |
|
1207 TFileName path = *iDbPath; |
|
1208 |
|
1209 path.Append(i < 10 ? i + '0' : i + 'a' - 10); |
|
1210 path.Append('\\'); |
|
1211 |
|
1212 if ( iFileServer.GetDir(path, KEntryAttDir, ESortNone, files) == KErrNone ) |
|
1213 { |
|
1214 CleanupStack::PushL( files ); |
|
1215 |
|
1216 for (TInt j = 0; j < files->Count(); j++) |
|
1217 { |
|
1218 TFileName tempPath( path ); |
|
1219 |
|
1220 tempPath.Append((*files)[j].iName); |
|
1221 |
|
1222 TInt error = KErrNone; |
|
1223 CDRMRightsData* rights = NULL; |
|
1224 |
|
1225 TRAP( error, rights = CDRMRightsData::OpenL( tempPath, iFileServer ) ); |
|
1226 if( rights ) |
|
1227 { |
|
1228 CleanupStack::PushL( rights ); |
|
1229 } |
|
1230 else |
|
1231 { |
|
1232 if( error != KErrNotFound ) |
|
1233 { |
|
1234 User::Leave( error ); |
|
1235 } |
|
1236 continue; |
|
1237 } |
|
1238 |
|
1239 const CDRMCommonData* data = rights->GetCommonDataL(); |
|
1240 |
|
1241 contentId = data->ContentID().AllocLC(); |
|
1242 aArray.AppendL( contentId ); |
|
1243 CleanupStack::Pop(); // contentId |
|
1244 |
|
1245 CleanupStack::PopAndDestroy(); // rights |
|
1246 } |
|
1247 |
|
1248 CleanupStack::PopAndDestroy(); // files |
|
1249 } |
|
1250 } |
|
1251 }; |
|
1252 |
|
1253 |
|
1254 // ----------------------------------------------------------------------------- |
|
1255 // CDRMRightsDB::WriteEncryptedStreamL |
|
1256 // The file will be opened and closed in CDRMBackup |
|
1257 // ----------------------------------------------------------------------------- |
|
1258 // |
|
1259 void CDRMRightsDB::WriteEncryptedStreamL( RWriteStream& aStream, |
|
1260 const TDesC8& aMessageData, |
|
1261 TDes8& aIv, |
|
1262 TDes8& aRemainder, |
|
1263 HBufC8*& aEncryptionBuffer, |
|
1264 TInt& aBytesWritten ) |
|
1265 { |
|
1266 TInt i = 0; |
|
1267 TInt n = 0; |
|
1268 TInt size = 0; |
|
1269 TPtr8 ptr(aEncryptionBuffer->Des()); |
|
1270 TPtrC8 data; |
|
1271 |
|
1272 data.Set(aMessageData); |
|
1273 if (aRemainder.Size() > 0 && aRemainder.Size() + data.Size() >= KEncryptionKeySize) |
|
1274 { |
|
1275 ptr.Copy(aRemainder); |
|
1276 n = Min(KEncryptionKeySize - aRemainder.Size(), data.Size()); |
|
1277 ptr.Append(data.Left(n)); |
|
1278 |
|
1279 EncryptL(aIv, ptr, EFalse); |
|
1280 |
|
1281 aStream.WriteL(ptr); |
|
1282 aBytesWritten += ptr.Size(); |
|
1283 aIv.Copy(ptr.Right(KEncryptionKeySize)); |
|
1284 data.Set(data.Right(data.Size() - n)); |
|
1285 aRemainder.SetLength(0); |
|
1286 } |
|
1287 |
|
1288 size = data.Size(); |
|
1289 for (i = 0; size > KEncryptionKeySize; i += KMaxEncryptionSize) |
|
1290 { |
|
1291 n = Min(KMaxEncryptionSize, ((size / KEncryptionKeySize) |
|
1292 * KEncryptionKeySize)); |
|
1293 ptr.Copy(data.Mid(i, n)); |
|
1294 |
|
1295 EncryptL(aIv, ptr, EFalse); |
|
1296 |
|
1297 aStream.WriteL(ptr); |
|
1298 aBytesWritten += ptr.Size(); |
|
1299 aIv.Copy(ptr.Right(KEncryptionKeySize)); |
|
1300 size -= n; |
|
1301 } |
|
1302 aRemainder.Append(data.Right(size)); |
|
1303 } |
|
1304 |
|
1305 |
|
1306 // ----------------------------------------------------------------------------- |
|
1307 // CDRMRightsDB::FinalizeEncryptedStreamL |
|
1308 // finalize the encryption |
|
1309 // ----------------------------------------------------------------------------- |
|
1310 void CDRMRightsDB::FinalizeEncryptedStreamL( RWriteStream& aStream, |
|
1311 TDes8& aIv, |
|
1312 TDes8& aRemainder, |
|
1313 HBufC8*& aEncryptionBuffer, |
|
1314 TInt& aBytesWritten ) |
|
1315 { |
|
1316 TPtr8 ptr(aEncryptionBuffer->Des()); |
|
1317 |
|
1318 ptr.Copy(aRemainder); |
|
1319 EncryptL(aIv, ptr, ETrue); |
|
1320 aStream.WriteL(ptr); |
|
1321 aStream.CommitL(); |
|
1322 aBytesWritten += ptr.Size(); |
|
1323 } |
|
1324 |
|
1325 |
|
1326 // ----------------------------------------------------------------------------- |
|
1327 // CDRMRightsDB::BackupContentToFileL |
|
1328 // The file will be opened and closed in CDRMBackup |
|
1329 // ----------------------------------------------------------------------------- |
|
1330 // |
|
1331 void CDRMRightsDB::BackupContentToFileL( RFile& aBackupFile, |
|
1332 const TDesC8& /* aEncryptionKey */, |
|
1333 const TInt /* aMode */ ) |
|
1334 { |
|
1335 //RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("BackupContentToFileL\n\r")); |
|
1336 // In UDT we need to check the mode |
|
1337 TInt fileSize = 0; |
|
1338 |
|
1339 TUint permissions = 0; |
|
1340 TUint8 continueMarker = 1; |
|
1341 RFile copyHandle; |
|
1342 TInt error = KErrNone; |
|
1343 |
|
1344 HBufC8* dataBuffer = NULL; // This is the buffer which gets reallocated |
|
1345 // if more space for data is required |
|
1346 // buf only if more space is needed, otherwise |
|
1347 // the size remains the same |
|
1348 // for start reserve as much as for the other buffer |
|
1349 // This is probably enough for all rights object |
|
1350 // But it's best to be sure |
|
1351 |
|
1352 TBuf8<KEncryptionKeySize> encIV; |
|
1353 TBuf8<KEncryptionKeySize> remainder; |
|
1354 HBufC8* encryptionBuffer = NULL; // The buffer used for the encryption in the middle |
|
1355 // reserved only once |
|
1356 TInt bytesWritten = 0; |
|
1357 TPtr8 writeData(NULL,0,0); |
|
1358 RMemWriteStream memStream; |
|
1359 |
|
1360 dataBuffer = HBufC8::NewLC( KMaxEncryptionSize ); |
|
1361 encryptionBuffer = HBufC8::NewLC( KMaxEncryptionSize ); |
|
1362 |
|
1363 User::LeaveIfError( copyHandle.Duplicate(aBackupFile) ); |
|
1364 |
|
1365 RFileWriteStream stream( copyHandle ); |
|
1366 CleanupClosePushL( stream ); |
|
1367 |
|
1368 // first write the first 4 bytes empty, in the end the size is written there |
|
1369 stream.WriteInt32L( fileSize ); |
|
1370 |
|
1371 #ifdef __DRM_OMA2 |
|
1372 AddUDTDataL( stream ); |
|
1373 #endif |
|
1374 |
|
1375 encIV.SetLength(KEncryptionKeySize); |
|
1376 // fill the iv with rnd data and write it to stream: |
|
1377 MDrmKeyStorage* storage = DrmKeyStorageNewL(); |
|
1378 |
|
1379 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
1380 CleanupStack::PushL(storageCleanup); |
|
1381 |
|
1382 storage->RandomDataGetL(encIV,KEncryptionKeySize); |
|
1383 CleanupStack::PopAndDestroy();//storageCleanup |
|
1384 |
|
1385 DRMLOG(_L("random encIV:")); |
|
1386 DRMLOGHEX(encIV); |
|
1387 |
|
1388 |
|
1389 stream.WriteL( encIV ); |
|
1390 |
|
1391 // loop over all the rights objects and write them to the file |
|
1392 |
|
1393 for (TInt i = 0; i < 16; i++) |
|
1394 { |
|
1395 CDir* files = NULL; |
|
1396 |
|
1397 TFileName path = *iDbPath; |
|
1398 |
|
1399 path.Append(i < 10 ? i + '0' : i + 'a' - 10); |
|
1400 path.Append('\\'); |
|
1401 |
|
1402 if ( iFileServer.GetDir(path, KEntryAttDir, ESortNone, files) == KErrNone ) |
|
1403 { |
|
1404 TInt j = 0; |
|
1405 |
|
1406 CleanupStack::PushL( files ); |
|
1407 |
|
1408 for (j = 0; j < files->Count(); j++) |
|
1409 { |
|
1410 TFileName tempPath( path ); |
|
1411 CDRMPointerArray<CDRMPermission> *permissionArray = CDRMPointerArray<CDRMPermission>::NewLC(); |
|
1412 permissionArray->SetAutoCleanup( ETrue ); |
|
1413 |
|
1414 tempPath.Append((*files)[j].iName); |
|
1415 |
|
1416 CDRMRightsData* rights = NULL; |
|
1417 |
|
1418 rights = CDRMRightsData::OpenLC( tempPath, iFileServer ); |
|
1419 |
|
1420 // WRITE THE GENERIC DATA ABOUT THE OBJECT |
|
1421 //----------------------------------------------------------- |
|
1422 // First count the size we want to use: |
|
1423 |
|
1424 |
|
1425 writeData.Set(&continueMarker, |
|
1426 sizeof(continueMarker), |
|
1427 sizeof(continueMarker)); |
|
1428 WriteEncryptedStreamL( stream, |
|
1429 writeData, |
|
1430 encIV, |
|
1431 remainder, |
|
1432 encryptionBuffer, |
|
1433 bytesWritten ); |
|
1434 |
|
1435 TInt sizeOfBuf = KEncryptionKeySize; // continue marker |
|
1436 |
|
1437 // Get the common data, Externalize it |
|
1438 CDRMCommonData* data = |
|
1439 const_cast<CDRMCommonData*>(rights->GetCommonDataL()); |
|
1440 sizeOfBuf += data->Size(); |
|
1441 |
|
1442 |
|
1443 // Realloc if needed, probably wont be: |
|
1444 if( sizeOfBuf > dataBuffer->Des().MaxSize() ) |
|
1445 { |
|
1446 dataBuffer->ReAllocL( sizeOfBuf ); |
|
1447 } |
|
1448 |
|
1449 // Write the size of the permission, used for decryption |
|
1450 writeData.Set( reinterpret_cast<TUint8*>(&sizeOfBuf), |
|
1451 sizeof(sizeOfBuf), |
|
1452 sizeof(sizeOfBuf)); |
|
1453 |
|
1454 WriteEncryptedStreamL( stream, |
|
1455 writeData, |
|
1456 encIV, |
|
1457 remainder, |
|
1458 encryptionBuffer, |
|
1459 bytesWritten ); |
|
1460 |
|
1461 |
|
1462 memStream.Open( (TAny*)( dataBuffer->Ptr() ), sizeOfBuf ); |
|
1463 CleanupClosePushL( memStream ); |
|
1464 |
|
1465 // The common data |
|
1466 data->ExternalizeL( memStream ); |
|
1467 |
|
1468 // The key |
|
1469 // Get the key, Externalize it |
|
1470 HBufC8* encKey = rights->GetKeyL(); |
|
1471 if( encKey == NULL ) |
|
1472 { |
|
1473 encKey = HBufC8::NewMaxL(KEncryptionKeySize); |
|
1474 Mem::FillZ( const_cast<TUint8*>(encKey->Ptr()), KEncryptionKeySize); |
|
1475 } |
|
1476 else |
|
1477 { |
|
1478 // Decrypt the key, the file is encrypted, it doesn't need to be twice |
|
1479 ModifyKey( *encKey ); |
|
1480 } |
|
1481 |
|
1482 CleanupStack::PushL( encKey ); |
|
1483 |
|
1484 memStream.WriteL( *encKey ); |
|
1485 CleanupStack::PopAndDestroy(); // enc key |
|
1486 |
|
1487 writeData.Set( const_cast<TUint8*>(dataBuffer->Ptr()), |
|
1488 sizeOfBuf, sizeOfBuf ); |
|
1489 |
|
1490 WriteEncryptedStreamL( stream, |
|
1491 writeData, |
|
1492 encIV, |
|
1493 remainder, |
|
1494 encryptionBuffer, |
|
1495 bytesWritten ); |
|
1496 |
|
1497 |
|
1498 CleanupStack::PopAndDestroy(); // memStream |
|
1499 |
|
1500 // Get the permissions and externalize their amount and them |
|
1501 // If there are none ignore the error and just save the normal data |
|
1502 TRAP(error, rights->FetchAllPermissionsL( *permissionArray ) ); |
|
1503 if( error ) |
|
1504 { |
|
1505 if( !( error == KErrCANoRights || error == KErrCANoPermission ) ) |
|
1506 { |
|
1507 User::LeaveIfError( error ); |
|
1508 } |
|
1509 } |
|
1510 |
|
1511 // WRITE THE AMOUNT OF PERMISSIONS |
|
1512 //----------------------------------------------------------- |
|
1513 permissions = permissionArray->Count(); |
|
1514 |
|
1515 writeData.Set(reinterpret_cast<TUint8*>(&permissions), |
|
1516 sizeof(permissions), |
|
1517 sizeof(permissions)); |
|
1518 |
|
1519 WriteEncryptedStreamL( stream, |
|
1520 writeData, |
|
1521 encIV, |
|
1522 remainder, |
|
1523 encryptionBuffer, |
|
1524 bytesWritten ); |
|
1525 |
|
1526 for( TInt count = 0; count < permissions; count++ ) |
|
1527 { |
|
1528 // WRITE EACH PERMISSION |
|
1529 //----------------------------------------------------------- |
|
1530 sizeOfBuf = (*permissionArray)[count]->Size(); |
|
1531 |
|
1532 // Realloc if needed, probably wont be: |
|
1533 if( sizeOfBuf > dataBuffer->Des().MaxSize() ) |
|
1534 { |
|
1535 dataBuffer->ReAllocL( sizeOfBuf ); |
|
1536 } |
|
1537 |
|
1538 // Write the size of the permission, used for decryption |
|
1539 writeData.Set(reinterpret_cast<TUint8*>(&sizeOfBuf), |
|
1540 sizeof(sizeOfBuf), |
|
1541 sizeof(sizeOfBuf)); |
|
1542 |
|
1543 WriteEncryptedStreamL( stream, |
|
1544 writeData, |
|
1545 encIV, |
|
1546 remainder, |
|
1547 encryptionBuffer, |
|
1548 bytesWritten ); |
|
1549 |
|
1550 // write the actual data |
|
1551 memStream.Open( (TAny*)( dataBuffer->Ptr() ), sizeOfBuf ); |
|
1552 CleanupClosePushL( memStream ); |
|
1553 |
|
1554 (*permissionArray)[count]->ExternalizeL( memStream ); |
|
1555 |
|
1556 writeData.Set( const_cast<TUint8*>(dataBuffer->Ptr()), |
|
1557 sizeOfBuf, sizeOfBuf ); |
|
1558 WriteEncryptedStreamL( stream, |
|
1559 writeData, |
|
1560 encIV, |
|
1561 remainder, |
|
1562 encryptionBuffer, |
|
1563 bytesWritten ); |
|
1564 |
|
1565 CleanupStack::PopAndDestroy(); // memstream |
|
1566 |
|
1567 } |
|
1568 CleanupStack::PopAndDestroy(2); // rights, permissionArray |
|
1569 } |
|
1570 |
|
1571 CleanupStack::PopAndDestroy(); // files |
|
1572 } |
|
1573 } |
|
1574 continueMarker = 0; |
|
1575 writeData.Set(&continueMarker, |
|
1576 sizeof(continueMarker), |
|
1577 sizeof(continueMarker)); |
|
1578 WriteEncryptedStreamL( stream, |
|
1579 writeData, |
|
1580 encIV, |
|
1581 remainder, |
|
1582 encryptionBuffer, |
|
1583 bytesWritten ); |
|
1584 |
|
1585 // Finalize the stream: |
|
1586 FinalizeEncryptedStreamL( stream, |
|
1587 encIV, |
|
1588 remainder, |
|
1589 encryptionBuffer, |
|
1590 bytesWritten ); |
|
1591 |
|
1592 CleanupStack::PopAndDestroy();// stream |
|
1593 |
|
1594 // Attach it to the file again, set the stream to the beginning |
|
1595 |
|
1596 User::LeaveIfError( copyHandle.Duplicate( aBackupFile ) ); |
|
1597 |
|
1598 stream.Attach( copyHandle ); |
|
1599 CleanupClosePushL( stream ); |
|
1600 |
|
1601 aBackupFile.Size( fileSize ); |
|
1602 |
|
1603 // write the size of the file including the 4 bytes in the start |
|
1604 stream.WriteInt32L( fileSize ); |
|
1605 |
|
1606 CleanupStack::PopAndDestroy(3); // stream, databuffer, encryptionbuffer |
|
1607 // DEBUG |
|
1608 // Perform restore: |
|
1609 // RestoreContentFromFileL( aBackupFile, *iKey, 0 ); |
|
1610 }; |
|
1611 |
|
1612 // ----------------------------------------------------------------------------- |
|
1613 // CDRMRightsDB::RestoreContentFromFileL |
|
1614 // The file will be opened and closed in CDRMBackup |
|
1615 // ----------------------------------------------------------------------------- |
|
1616 // |
|
1617 void CDRMRightsDB::RestoreContentFromFileL( RFile& aBackupFile, |
|
1618 const TDesC8& aEncryptionKey, |
|
1619 const TInt aMode ) |
|
1620 { |
|
1621 // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreContentFromFileL\n\r")); |
|
1622 TInt8 continueMarker = 1; |
|
1623 TBuf8<16> key; |
|
1624 TBuf8<16> encryptionKey; |
|
1625 TInt permissions = 0; |
|
1626 CDRMPermission* permission = CDRMPermission::NewLC(); |
|
1627 CDRMCommonData *commonData = NULL; |
|
1628 CDRMPointerArray<CDRMPermission> *permissionArray = CDRMPointerArray<CDRMPermission>::NewLC(); |
|
1629 permissionArray->SetAutoCleanup( ETrue ); |
|
1630 TDRMUniqueID uniqueID = 0; |
|
1631 RFile fileHandle; |
|
1632 TInt readPos = 0; |
|
1633 TInt size = 0; |
|
1634 TInt dataLeft = 0; |
|
1635 TPtr8 keyData(NULL,0,0); |
|
1636 |
|
1637 // maintain knowledge about stateful rights not being restored |
|
1638 TBool stateful = EFalse; |
|
1639 |
|
1640 |
|
1641 DRMLOG( _L( "CDRMRightsDB::RestoreContentFromFileL ->" ) ); |
|
1642 |
|
1643 // Indicate that the DB is updated |
|
1644 iLastUpdate.HomeTime(); |
|
1645 |
|
1646 key.SetLength( KEncryptionKeySize ); |
|
1647 fileHandle.Duplicate( aBackupFile ); |
|
1648 CleanupClosePushL( fileHandle ); |
|
1649 |
|
1650 HBufC8* dataBuffer = NULL; // This is the buffer which gets reallocated |
|
1651 // if more space for data is required |
|
1652 // buf only if more space is needed, otherwise |
|
1653 // the size remains the same |
|
1654 // for start reserve as much as for the other buffer |
|
1655 // This is probably enough for all rights object |
|
1656 // But it's best to be sure |
|
1657 |
|
1658 TBuf8<KEncryptionKeySize> encIV; |
|
1659 |
|
1660 TPtr8 readData(NULL,0,0); |
|
1661 |
|
1662 switch( aMode ) |
|
1663 { |
|
1664 case KDRMNormalBackup: |
|
1665 { |
|
1666 encryptionKey.Copy( *iKey ); |
|
1667 } |
|
1668 break; |
|
1669 case KDRMUDTBackup: |
|
1670 { |
|
1671 encryptionKey.Copy(aEncryptionKey); |
|
1672 } |
|
1673 break; |
|
1674 default: |
|
1675 User::Leave( KErrArgument ); |
|
1676 } |
|
1677 |
|
1678 encryptionKey.SetLength(KEncryptionKeySize); |
|
1679 |
|
1680 |
|
1681 dataBuffer = HBufC8::NewLC( KMaxEncryptionSize ); |
|
1682 |
|
1683 encIV.SetLength( KEncryptionKeySize ); |
|
1684 |
|
1685 // Check that the decryption works, if it doesn't then the |
|
1686 // key is faulty |
|
1687 User::LeaveIfError( aBackupFile.Size( readPos ) ); |
|
1688 if( readPos < KUdtDataPos+KMaxUDTDataSize+(KEncryptionKeySize*2) ) |
|
1689 { |
|
1690 // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreContentFromFileL : corrupt\n\r")); |
|
1691 User::Leave(KErrCorrupt); |
|
1692 } |
|
1693 readPos -= KEncryptionKeySize*2; |
|
1694 |
|
1695 User::LeaveIfError( fileHandle.Seek( ESeekStart, readPos ) ); |
|
1696 |
|
1697 // Read the IV |
|
1698 readData.Set( const_cast<TUint8*>(encIV.Ptr()), 0, KEncryptionKeySize ); |
|
1699 User::LeaveIfError( fileHandle.Read( readData, KEncryptionKeySize ) ); |
|
1700 |
|
1701 // Read the data: |
|
1702 readData.Set( const_cast<TUint8*>( dataBuffer->Ptr()), 0, |
|
1703 KEncryptionKeySize ); |
|
1704 User::LeaveIfError( fileHandle.Read( readData, KEncryptionKeySize ) ); |
|
1705 |
|
1706 DecryptL( encIV, readData, EFalse, encryptionKey ); |
|
1707 |
|
1708 // Check if the padding matches, if not the function will leave |
|
1709 CheckPaddingL( readData ); |
|
1710 |
|
1711 // End checking |
|
1712 |
|
1713 // Now we are ready to go through the file |
|
1714 //----------------------------------------------------------------------- |
|
1715 |
|
1716 // Duplicate file handle |
|
1717 readPos = KUdtDataPos+KMaxUDTDataSize; |
|
1718 User::LeaveIfError( fileHandle.Seek( ESeekStart, readPos ) ); |
|
1719 iMemStream.Close(); |
|
1720 |
|
1721 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1722 dataLeft, size, ETrue, encryptionKey ); |
|
1723 |
|
1724 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1725 |
|
1726 // Read data now contains decrypted data which we can go through |
|
1727 |
|
1728 // loop over all the rights objects and merge them to the db |
|
1729 while( true ) |
|
1730 { |
|
1731 keyData.Set(const_cast<TUint8*>(key.Ptr()), 0, KEncryptionKeySize); |
|
1732 |
|
1733 if( dataLeft < 1 ) |
|
1734 { |
|
1735 size = 1; |
|
1736 iMemStream.Close(); |
|
1737 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1738 dataLeft, size, EFalse, encryptionKey ); |
|
1739 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1740 } |
|
1741 |
|
1742 continueMarker = iMemStream.ReadInt8L(); |
|
1743 dataLeft -= 1; |
|
1744 |
|
1745 if( !continueMarker ) |
|
1746 { |
|
1747 // RFileLogger::Write(KLogDir, KLogName, EFileLoggingModeAppend, _L8("RestoreContentFromFileL : exit from loop\n\r")); |
|
1748 break; |
|
1749 } |
|
1750 |
|
1751 if( dataLeft < 4 ) |
|
1752 { |
|
1753 size = 4; |
|
1754 iMemStream.Close(); |
|
1755 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1756 dataLeft, size, EFalse, encryptionKey ); |
|
1757 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1758 } |
|
1759 |
|
1760 // Read the size of the data: |
|
1761 size = iMemStream.ReadInt32L(); |
|
1762 dataLeft -= 4; |
|
1763 |
|
1764 if( size > dataLeft ) |
|
1765 { |
|
1766 iMemStream.Close(); |
|
1767 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1768 dataLeft, size, EFalse, encryptionKey ); |
|
1769 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()),dataLeft); |
|
1770 } |
|
1771 |
|
1772 // Read the common data: |
|
1773 commonData = CDRMCommonData::NewLC(); |
|
1774 commonData->InternalizeL(iMemStream); |
|
1775 |
|
1776 // Read the content encryption key |
|
1777 iMemStream.ReadL( keyData, KEncryptionKeySize ); |
|
1778 dataLeft -= size; |
|
1779 |
|
1780 if( dataLeft < 4 ) |
|
1781 { |
|
1782 size = 4; |
|
1783 iMemStream.Close(); |
|
1784 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1785 dataLeft, size, EFalse, encryptionKey ); |
|
1786 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1787 } |
|
1788 |
|
1789 // read the amount of permissions |
|
1790 permissions = iMemStream.ReadInt32L(); |
|
1791 dataLeft -= 4; |
|
1792 |
|
1793 |
|
1794 // Create the entry if needed |
|
1795 TFileName path; |
|
1796 TInt error = KErrNone; |
|
1797 CDRMRightsData* rights = NULL; |
|
1798 TBuf8<16> nullDesc; |
|
1799 TBuf<16> nullDesc2; |
|
1800 HBufC8* oldKey = NULL; |
|
1801 TInt8 insertPerm = 1; |
|
1802 TBool doInsert = ETrue; |
|
1803 TBool keyExists = EFalse; |
|
1804 |
|
1805 for( TInt counter = 0; counter < KEncryptionKeySize; counter++ ) |
|
1806 { |
|
1807 if( key[counter] != 0x00 ) |
|
1808 { |
|
1809 keyExists = ETrue; |
|
1810 counter = KEncryptionKeySize; |
|
1811 } |
|
1812 } |
|
1813 |
|
1814 |
|
1815 // Encrypt the key |
|
1816 if( keyExists ) |
|
1817 { |
|
1818 ModifyKey( key ); |
|
1819 } |
|
1820 |
|
1821 GetRightsFileNameL( commonData->ContentID(), path); |
|
1822 |
|
1823 // Indicate that the DB is updated |
|
1824 iLastUpdate.HomeTime(); |
|
1825 |
|
1826 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
1827 |
|
1828 if( error == KErrNotFound ) |
|
1829 { |
|
1830 // Indicate that the DB is updated |
|
1831 iLastUpdate.HomeTime(); |
|
1832 |
|
1833 if( keyExists ) |
|
1834 { |
|
1835 TRAP(error, rights = CDRMRightsData::NewL( commonData, key, path, iFileServer ) ); |
|
1836 } |
|
1837 else |
|
1838 { |
|
1839 TRAP(error, rights = CDRMRightsData::NewL( commonData, KNullDesC8, path, iFileServer ) ); |
|
1840 } |
|
1841 |
|
1842 CleanupStack::Pop(); // Pop Common Data |
|
1843 CleanupStack::PushL(rights); // Push the rights in: |
|
1844 insertPerm = -1; |
|
1845 } |
|
1846 else |
|
1847 { |
|
1848 // Destroy common data if it already exits per OpenL |
|
1849 CleanupStack::PopAndDestroy(); |
|
1850 |
|
1851 // Leave if another error occurred |
|
1852 User::LeaveIfError( error ); |
|
1853 |
|
1854 if( rights ) |
|
1855 { |
|
1856 CleanupStack::PushL( rights ); |
|
1857 oldKey = rights->GetKeyL(); |
|
1858 |
|
1859 // if there is no key and there is one in the new one |
|
1860 if( !oldKey && keyExists ) |
|
1861 { |
|
1862 insertPerm = 0; |
|
1863 } |
|
1864 else if( oldKey && key.Compare( *oldKey ) ) // If the key is different |
|
1865 { |
|
1866 insertPerm = 0; |
|
1867 } |
|
1868 if( oldKey ) |
|
1869 { |
|
1870 delete oldKey; |
|
1871 } |
|
1872 } |
|
1873 } |
|
1874 |
|
1875 if( !rights ) |
|
1876 { |
|
1877 User::Leave( KErrGeneral ); |
|
1878 } |
|
1879 |
|
1880 |
|
1881 |
|
1882 |
|
1883 if( insertPerm == -1 ) // Add everything no checks needed |
|
1884 { |
|
1885 for( TInt count = 0; count < permissions; count++ ) |
|
1886 { |
|
1887 if( dataLeft < 4 ) |
|
1888 { |
|
1889 size = 4; |
|
1890 iMemStream.Close(); |
|
1891 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1892 dataLeft, size, EFalse, encryptionKey ); |
|
1893 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1894 } |
|
1895 |
|
1896 // Read the size of the data: |
|
1897 size = iMemStream.ReadInt32L(); |
|
1898 dataLeft -= 4; |
|
1899 |
|
1900 if( size > dataLeft ) |
|
1901 { |
|
1902 iMemStream.Close(); |
|
1903 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1904 dataLeft, size, EFalse, encryptionKey ); |
|
1905 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1906 } |
|
1907 |
|
1908 permission->InternalizeL( iMemStream ); |
|
1909 dataLeft -= size; |
|
1910 |
|
1911 if( !permission->Stateful() || aMode == KDRMUDTBackup ) |
|
1912 { |
|
1913 rights->StoreNewPermissionL( *permission, uniqueID ); |
|
1914 } |
|
1915 else if( !stateful ) |
|
1916 { |
|
1917 stateful = ETrue; |
|
1918 } |
|
1919 } |
|
1920 } |
|
1921 else if( insertPerm == 1) // Add stuff that doesn't match the times |
|
1922 { |
|
1923 // Indicate that the DB is updated |
|
1924 iLastUpdate.HomeTime(); |
|
1925 |
|
1926 // If there are no rights that's an ok thing |
|
1927 // Fix memory handling |
|
1928 TRAP( error, rights->FetchAllPermissionsL( *permissionArray ) ); |
|
1929 if( error ) |
|
1930 { |
|
1931 if( !( error == KErrCANoRights || |
|
1932 error == KErrCANoPermission ) ) |
|
1933 { |
|
1934 User::LeaveIfError(error); |
|
1935 } |
|
1936 |
|
1937 } |
|
1938 |
|
1939 |
|
1940 for( TInt count = 0; count < permissions; count++ ) |
|
1941 { |
|
1942 if( dataLeft < 4 ) |
|
1943 { |
|
1944 size = 4; |
|
1945 iMemStream.Close(); |
|
1946 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1947 dataLeft, size, EFalse, encryptionKey ); |
|
1948 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1949 } |
|
1950 |
|
1951 // Read the size of the data: |
|
1952 size = iMemStream.ReadInt32L(); |
|
1953 dataLeft -= 4; |
|
1954 |
|
1955 if( size > dataLeft ) |
|
1956 { |
|
1957 iMemStream.Close(); |
|
1958 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
1959 dataLeft, size, EFalse, encryptionKey ); |
|
1960 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
1961 } |
|
1962 |
|
1963 permission->InternalizeL( iMemStream ); |
|
1964 dataLeft -= size; |
|
1965 |
|
1966 doInsert = ETrue; |
|
1967 |
|
1968 for( TInt perm = 0; perm < permissionArray->Count(); perm++) |
|
1969 { |
|
1970 if( (*permissionArray)[perm]->iOriginalInsertTime == |
|
1971 permission->iOriginalInsertTime ) |
|
1972 { |
|
1973 doInsert = EFalse; |
|
1974 break; |
|
1975 } |
|
1976 } |
|
1977 |
|
1978 if( doInsert && (!permission->Stateful() || aMode == KDRMUDTBackup ) ) |
|
1979 { |
|
1980 rights->StoreNewPermissionL( *permission, uniqueID ); |
|
1981 } |
|
1982 else if( doInsert && !stateful ) |
|
1983 { |
|
1984 stateful = ETrue; |
|
1985 } |
|
1986 } |
|
1987 permissionArray->ResetAndDestroy(); |
|
1988 } |
|
1989 else // Just read it all but dont add anything |
|
1990 { |
|
1991 // Indicate that the DB is updated |
|
1992 iLastUpdate.HomeTime(); |
|
1993 |
|
1994 for( TInt count = 0; count < permissions; count++ ) |
|
1995 { |
|
1996 if( dataLeft < 4 ) |
|
1997 { |
|
1998 size = 4; |
|
1999 iMemStream.Close(); |
|
2000 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
2001 dataLeft, size, EFalse, encryptionKey ); |
|
2002 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
2003 } |
|
2004 |
|
2005 // Read the size of the data: |
|
2006 size = iMemStream.ReadInt32L(); |
|
2007 dataLeft -= 4; |
|
2008 |
|
2009 if( size > dataLeft ) |
|
2010 { |
|
2011 iMemStream.Close(); |
|
2012 ReadDataL( fileHandle, encIV, readData, dataBuffer, |
|
2013 dataLeft, size, EFalse, encryptionKey ); |
|
2014 iMemStream.Open( const_cast<TUint8*>( readData.Ptr()), dataLeft); |
|
2015 |
|
2016 } |
|
2017 |
|
2018 permission->InternalizeL( iMemStream ); |
|
2019 dataLeft -= size; |
|
2020 } |
|
2021 } |
|
2022 CleanupStack::PopAndDestroy(); // rights |
|
2023 } |
|
2024 iMemStream.Close(); |
|
2025 CleanupStack::PopAndDestroy( 4 ); // permission, permissionArray, fileHandle, dataBuffer |
|
2026 |
|
2027 DRMLOG( _L( "CDRMRightsDB::RestoreContentFromFileL ->" ) ); |
|
2028 |
|
2029 // If there are stateful rights not put to the phone, this is always EFalse for |
|
2030 // the UDT case leave with the special error case to leave the restored database |
|
2031 // to enable UDT |
|
2032 if( stateful ) |
|
2033 { |
|
2034 User::Leave( KErrPermissionDenied ); |
|
2035 } |
|
2036 }; |
|
2037 |
|
2038 |
|
2039 |
|
2040 // ----------------------------------------------------------------------------- |
|
2041 // CDRMRightsDB::HashContentID |
|
2042 // removed the cid: or flk: from the beginning of the content ID before hashing |
|
2043 // ----------------------------------------------------------------------------- |
|
2044 // |
|
2045 void CDRMRightsDB::HashContentID( TPtrC8& aHashKey, const TDesC8& aContentID ) |
|
2046 { |
|
2047 TPtrC8 cid; |
|
2048 iHasher->Reset(); |
|
2049 |
|
2050 if ( !aContentID.Left( KFLKStringLength ).Compare( KFLKString ) ) |
|
2051 { |
|
2052 cid.Set( aContentID.Right( aContentID.Length()-KCIDStringLength ) ); |
|
2053 } |
|
2054 else if ( !aContentID.Left( KCIDStringLength ).Compare( KCIDString ) ) |
|
2055 { |
|
2056 cid.Set( aContentID.Right( aContentID.Length()-KCIDStringLength ) ); |
|
2057 } |
|
2058 else |
|
2059 { |
|
2060 cid.Set( aContentID ); |
|
2061 } |
|
2062 |
|
2063 aHashKey.Set( iHasher->Hash( cid ) ); |
|
2064 }; |
|
2065 |
|
2066 |
|
2067 // ----------------------------------------------------------------------------- |
|
2068 // CDRMRightsDB::GetRightsFileNameL |
|
2069 // |
|
2070 // ----------------------------------------------------------------------------- |
|
2071 // |
|
2072 void CDRMRightsDB::GetRightsFileNameL( |
|
2073 const TDesC8& aContentID, |
|
2074 TFileName& aPath) |
|
2075 { |
|
2076 TPtrC8 hash; |
|
2077 TInt i; |
|
2078 TInt v; |
|
2079 |
|
2080 aPath.Copy(*iDbPath); |
|
2081 HashContentID(hash, aContentID); |
|
2082 v = hash[0] >> 4; |
|
2083 aPath.Append(v < 10 ? v + '0' : v + 'a' - 10); |
|
2084 aPath.Append('\\'); |
|
2085 for (i = 0; i < hash.Length(); i++) |
|
2086 { |
|
2087 v = hash[i] >> 4; |
|
2088 aPath.Append(v < 10 ? v + '0' : v + 'a' - 10); |
|
2089 v = hash[i] & 0x0f; |
|
2090 aPath.Append(v < 10 ? v + '0' : v + 'a' - 10); |
|
2091 } |
|
2092 aPath.Append(KROExtension); |
|
2093 } |
|
2094 |
|
2095 // ----------------------------------------------------------------------------- |
|
2096 // CDRMRightsDB::GetXMLFileNameL |
|
2097 // ----------------------------------------------------------------------------- |
|
2098 // |
|
2099 void CDRMRightsDB::GetXMLFileNameL( |
|
2100 const TDesC8& aRoID, |
|
2101 TFileName& aPath) |
|
2102 { |
|
2103 TPtrC8 hash; |
|
2104 TInt i; |
|
2105 TInt v; |
|
2106 |
|
2107 aPath.Copy(*iDbPath); |
|
2108 HashContentID(hash, aRoID); |
|
2109 aPath.Append(KRODirName); |
|
2110 for (i = 0; i < hash.Length(); i++) |
|
2111 { |
|
2112 v = hash[i] >> 4; |
|
2113 aPath.Append(v < 10 ? v + '0' : v + 'a' - 10); |
|
2114 v = hash[i] & 0x0f; |
|
2115 aPath.Append(v < 10 ? v + '0' : v + 'a' - 10); |
|
2116 } |
|
2117 aPath.Append(KXmlExtension); |
|
2118 } |
|
2119 |
|
2120 // ----------------------------------------------------------------------------- |
|
2121 // CDRMRightsDB::InitializeDatabaseL |
|
2122 // initializes the database for use, called before every external interface |
|
2123 // function ( not NewL, NewLC ) |
|
2124 // (other items were commented in a header). |
|
2125 // ----------------------------------------------------------------------------- |
|
2126 // |
|
2127 void CDRMRightsDB::InitializeDatabaseL(void) |
|
2128 { |
|
2129 TInt i; |
|
2130 TFileName path; |
|
2131 |
|
2132 DRMLOG( _L( "CDRMRightsDB::InitializeDatabaseL ->" ) ); |
|
2133 |
|
2134 iFileServer.MkDirAll(*iDbPath); |
|
2135 for (i = 0; i < 16; i++) |
|
2136 { |
|
2137 // Indicate that the DB is updated |
|
2138 iLastUpdate.HomeTime(); |
|
2139 |
|
2140 path.Copy(*iDbPath); |
|
2141 path.Append(i < 10 ? i + '0' : i + 'a' - 10); |
|
2142 path.Append('\\'); |
|
2143 iFileServer.MkDir(path); |
|
2144 } |
|
2145 |
|
2146 // Indicate that the DB is updated |
|
2147 iLastUpdate.HomeTime(); |
|
2148 |
|
2149 // Domain RO XML dir |
|
2150 path.Copy(*iDbPath); |
|
2151 path.Append(KRODirName); |
|
2152 iFileServer.MkDirAll(path); |
|
2153 |
|
2154 DRMLOG( _L( "CDRMRightsDB::InitializeDatabaseL <-" ) ); |
|
2155 }; |
|
2156 |
|
2157 // ----------------------------------------------------------------------------- |
|
2158 // CDRMRightsDB::GetXMLFileNameL |
|
2159 // ----------------------------------------------------------------------------- |
|
2160 // |
|
2161 void CDRMRightsDB::ModifyKey( TDesC8& aKey ) |
|
2162 { |
|
2163 TInt* ptrOriginal = NULL; |
|
2164 TInt* ptrCryptKey = NULL; |
|
2165 |
|
2166 // Cast into TInt pointers |
|
2167 ptrOriginal = reinterpret_cast<TInt*>( const_cast<TUint8*>( aKey.Ptr() ) ); |
|
2168 ptrCryptKey = reinterpret_cast<TInt*>( const_cast<TUint8*>( iKey->Ptr() ) ); |
|
2169 |
|
2170 // XOR the key with the DB key |
|
2171 ptrOriginal[0] ^= ptrCryptKey[0]; |
|
2172 ptrOriginal[1] ^= ptrCryptKey[1]; |
|
2173 ptrOriginal[2] ^= ptrCryptKey[2]; |
|
2174 ptrOriginal[3] ^= ptrCryptKey[3]; |
|
2175 }; |
|
2176 |
|
2177 // ----------------------------------------------------------------------------- |
|
2178 // CDRMRightsDB::AddUDTDataL |
|
2179 // EB = 00 || BT || PS || 00 || D |
|
2180 // ----------------------------------------------------------------------------- |
|
2181 // |
|
2182 #ifdef __DRM_OMA2 |
|
2183 void CDRMRightsDB::AddUDTDataL( RWriteStream& aStream ) |
|
2184 #else |
|
2185 void CDRMRightsDB::AddUDTDataL( RWriteStream& ) |
|
2186 #endif // __DRM_OMA2 |
|
2187 { |
|
2188 #ifdef __DRM_OMA2 |
|
2189 TBuf8<MDrmKeyStorage::KRdbSerialNumberLength> serialNumber; |
|
2190 TBuf8<KMaxUDTDataSize> buffer; |
|
2191 TUint8* ptr = const_cast<TUint8*>(buffer.Ptr()); |
|
2192 HBufC8* result = NULL; |
|
2193 TPtr8 udtData( ptr+KDeviceDataBlock, KDeviceDataBlock, KDeviceDataBlock ); |
|
2194 HBufC8* phoneSerialNumber = NULL; |
|
2195 TInt pos = 0; |
|
2196 |
|
2197 MDrmKeyStorage* storage = DrmKeyStorageNewL(); |
|
2198 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
2199 CleanupStack::PushL(storageCleanup); |
|
2200 |
|
2201 storage->GetRdbSerialNumberL( serialNumber ); |
|
2202 |
|
2203 // Fill the descriptor with random data |
|
2204 |
|
2205 TPtr8 random( const_cast<TUint8*>(buffer.Ptr()), |
|
2206 KMaxUDTDataSize, |
|
2207 KMaxUDTDataSize ); |
|
2208 |
|
2209 storage->RandomDataGetL(random,KMaxUDTDataSize); |
|
2210 |
|
2211 DRMLOG(_L("random UDTData:")); |
|
2212 DRMLOGHEX(buffer); |
|
2213 |
|
2214 // Get the serial number: |
|
2215 phoneSerialNumber = CnvUtfConverter::ConvertFromUnicodeToUtf8L( *iImei ); |
|
2216 CleanupStack::PushL( phoneSerialNumber ); |
|
2217 |
|
2218 // Device public key encrypted Rights Database Serial Number 128 bytes |
|
2219 // Device public key encrypted Rights Database Encryption Key 128 bytes |
|
2220 // ---------------------------------------------------------- |
|
2221 // 00 || 02 || padding || 00 || 16bytes || 16 bytes |
|
2222 |
|
2223 // Construct the 128 bit buffer |
|
2224 ptr = const_cast<TUint8*>(udtData.Ptr()); |
|
2225 |
|
2226 // Set the first byte to 0 |
|
2227 // Set the padding type as random padding |
|
2228 ptr[0] = 0x00; |
|
2229 ptr[1] = 0x02; |
|
2230 |
|
2231 pos = KDeviceDataBlock; |
|
2232 pos -= KEncryptionKeySize; |
|
2233 |
|
2234 // insert the key |
|
2235 udtData.Replace( pos, KEncryptionKeySize, *iKey ); |
|
2236 |
|
2237 pos -= MDrmKeyStorage::KRdbSerialNumberLength; |
|
2238 |
|
2239 // insert the db serial number |
|
2240 udtData.Replace( pos, MDrmKeyStorage::KRdbSerialNumberLength, serialNumber ); |
|
2241 |
|
2242 // insert the finish padding block |
|
2243 pos = pos - 1; |
|
2244 ptr[pos] = 0x00; |
|
2245 |
|
2246 result = storage->RsaSignL( udtData ); |
|
2247 CleanupStack::PushL( result ); |
|
2248 |
|
2249 // Write the data to the stream |
|
2250 aStream.WriteL( *result, KDeviceDataBlock ); |
|
2251 |
|
2252 CleanupStack::PopAndDestroy(); // result |
|
2253 |
|
2254 // Device public key encrypted Device serial number 128 bytes |
|
2255 // ---------------------------------------------------------- |
|
2256 // 00 || 02 || padding || 00 || Size || Imei |
|
2257 |
|
2258 // Construct the 128 bit buffer |
|
2259 ptr = const_cast<TUint8*>(buffer.Ptr()); |
|
2260 udtData.Set( ptr, KDeviceDataBlock, KDeviceDataBlock ); |
|
2261 ptr = const_cast<TUint8*>(udtData.Ptr()); |
|
2262 |
|
2263 // Set the first byte to 0 |
|
2264 // Set the padding type as random padding |
|
2265 ptr[0] = 0x00; |
|
2266 ptr[1] = 0x02; |
|
2267 |
|
2268 pos = KDeviceDataBlock; |
|
2269 pos -= phoneSerialNumber->Length(); |
|
2270 |
|
2271 // insert the phone serial number |
|
2272 |
|
2273 udtData.Replace( pos, phoneSerialNumber->Length(), *phoneSerialNumber ); |
|
2274 |
|
2275 pos -= 1; |
|
2276 |
|
2277 // insert the db serial number |
|
2278 ptr[pos] = phoneSerialNumber->Length(); |
|
2279 |
|
2280 // insert the finish padding block |
|
2281 pos -= 1; |
|
2282 ptr[pos] = 0x00; |
|
2283 |
|
2284 result = storage->RsaSignL( udtData ); |
|
2285 CleanupStack::PushL( result ); |
|
2286 |
|
2287 // Write the data to the stream |
|
2288 aStream.WriteL( *result, KDeviceDataBlock ); |
|
2289 |
|
2290 CleanupStack::PopAndDestroy(); // result |
|
2291 |
|
2292 ptr = const_cast<TUint8*>(buffer.Ptr()); |
|
2293 |
|
2294 // UDT public key encrypted Rights Database Serial Number 256 bytes |
|
2295 // UDT public key encrypted Rights Database Encryption Key 256 bytes |
|
2296 // ---------------------------------------------------------- |
|
2297 // 00 || 02 || padding || 00 || Size || Imei || 16bytes || 16 bytes |
|
2298 |
|
2299 // Fill the descriptor with random data |
|
2300 storage->RandomDataGetL(random,KMaxUDTDataSize); |
|
2301 |
|
2302 DRMLOG(_L("random UDTData:")); |
|
2303 DRMLOGHEX(buffer); |
|
2304 |
|
2305 // Make the beginning of the buffer correct for use: |
|
2306 ptr = const_cast<TUint8*>(buffer.Ptr()); |
|
2307 udtData.Set( ptr, KMaxUDTDataSize, KMaxUDTDataSize ); |
|
2308 ptr[0] = 0x00; |
|
2309 ptr[1] = 0x02; |
|
2310 |
|
2311 pos = KMaxUDTDataSize; |
|
2312 pos -= KEncryptionKeySize; |
|
2313 |
|
2314 // insert the key |
|
2315 udtData.Replace( pos, KEncryptionKeySize, *iKey ); |
|
2316 |
|
2317 pos -= MDrmKeyStorage::KRdbSerialNumberLength; |
|
2318 |
|
2319 // insert the db serial number |
|
2320 udtData.Replace( pos, MDrmKeyStorage::KRdbSerialNumberLength, serialNumber ); |
|
2321 |
|
2322 // insert the phone serial number |
|
2323 pos -= phoneSerialNumber->Length(); |
|
2324 udtData.Replace( pos, phoneSerialNumber->Length(), *phoneSerialNumber ); |
|
2325 |
|
2326 pos -= 4; |
|
2327 |
|
2328 // insert the size of the phoneSerialNumber field |
|
2329 WriteIntToBlock( phoneSerialNumber->Length(), udtData, pos ); |
|
2330 |
|
2331 // insert the finish padding block |
|
2332 pos -= 1; |
|
2333 ptr[pos] = 0x00; |
|
2334 TInt error = KErrNone; |
|
2335 |
|
2336 TPtrC8 createData( udtData.Mid(pos+1)); |
|
2337 |
|
2338 TRAP( error, result = storage->UdtEncryptL( createData )); |
|
2339 // No udt certificate write the block but empty |
|
2340 if( error ) |
|
2341 { |
|
2342 result = HBufC8::NewMaxL( 256 ); |
|
2343 Mem::FillZ( const_cast<TUint8*>(result->Ptr()), 256); |
|
2344 } |
|
2345 CleanupStack::PushL( result ); |
|
2346 |
|
2347 aStream.WriteL( *result, 256 ); |
|
2348 |
|
2349 CleanupStack::PopAndDestroy(3); //result,phoneSerialNumber, storageCleanup |
|
2350 #else |
|
2351 User::Leave(KErrNotSupported); |
|
2352 #endif |
|
2353 }; |
|
2354 |
|
2355 // test function |
|
2356 void CDRMRightsDB::CreateDummyUDTFileL() |
|
2357 { |
|
2358 #ifdef __DRM_OMA2 |
|
2359 TFileName backupFile; |
|
2360 RFile input; |
|
2361 TInt fileSize = 4 + 256 + 256; |
|
2362 |
|
2363 backupFile.Copy( _L("c:\\") ); |
|
2364 backupFile.Append( KRightsDbBackupFile ); |
|
2365 |
|
2366 // Open the udt file |
|
2367 User::LeaveIfError( input.Replace( iFileServer, backupFile, EFileRead|EFileWrite ) ); |
|
2368 RFileWriteStream stream( input, 0); |
|
2369 |
|
2370 stream.WriteInt32L( fileSize ); |
|
2371 CleanupClosePushL(stream); |
|
2372 |
|
2373 AddUDTDataL( stream ); |
|
2374 CleanupStack::PopAndDestroy(); |
|
2375 #else |
|
2376 User::Leave(KErrNotSupported); |
|
2377 #endif // __DRM_OMA2 |
|
2378 }; |
|
2379 |
|
2380 |
|
2381 // ----------------------------------------------------------------------------- |
|
2382 // CDRMRightsDB::CleanUdtData |
|
2383 // ----------------------------------------------------------------------------- |
|
2384 // |
|
2385 void CDRMRightsDB::CleanUdtData() |
|
2386 { |
|
2387 #ifdef __DRM_OMA2 |
|
2388 TFileName backupFile; |
|
2389 |
|
2390 #ifndef RD_MULTIPLE_DRIVE |
|
2391 |
|
2392 backupFile.Copy( KBackupDirectory ); |
|
2393 |
|
2394 #else //RD_MULTIPLE_DRIVE |
|
2395 |
|
2396 TInt driveNumber( -1 ); |
|
2397 TChar driveLetter; |
|
2398 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
2399 iFileServer.DriveToChar( driveNumber, driveLetter ); |
|
2400 |
|
2401 TFileName backupDir; |
|
2402 backupDir.Format( KBackupDir, (TUint)driveLetter ); |
|
2403 |
|
2404 backupFile.Copy( backupDir ); |
|
2405 |
|
2406 #endif |
|
2407 |
|
2408 backupFile.Append( KRightsDbBackupFile ); |
|
2409 |
|
2410 // Open the udt file |
|
2411 iFileServer.Delete( backupFile ); |
|
2412 #endif // __DRM_OMA2 |
|
2413 }; |
|
2414 |
|
2415 // ----------------------------------------------------------------------------- |
|
2416 // CDRMRightsDB::EncryptL |
|
2417 // |
|
2418 // ----------------------------------------------------------------------------- |
|
2419 // // iRdb.Encrypt(aIv, ptr, ETrue); |
|
2420 void CDRMRightsDB::EncryptL( const TDesC8& aIv, |
|
2421 TPtr8& aData, |
|
2422 TBool aAddPadding ) |
|
2423 { |
|
2424 CAESEncryptor* aes = NULL; |
|
2425 CModeCBCEncryptor* cbc = NULL; |
|
2426 TInt i; |
|
2427 TInt lastBlockStart; |
|
2428 TInt dataLength; |
|
2429 TInt padding; |
|
2430 TPtr8 d(NULL, 0); |
|
2431 |
|
2432 aes = CAESEncryptor::NewLC(*iKey); |
|
2433 cbc = CModeCBCEncryptor::NewL(aes, aIv); |
|
2434 CleanupStack::Pop(); // aes, now owned by cbc |
|
2435 CleanupStack::PushL(cbc); |
|
2436 |
|
2437 dataLength = aData.Length(); |
|
2438 lastBlockStart = (dataLength / KEncryptionKeySize) * KEncryptionKeySize; |
|
2439 for (i = 0; i < lastBlockStart; i += KEncryptionKeySize) |
|
2440 { |
|
2441 d.Set(aData.MidTPtr (i, KEncryptionKeySize)); |
|
2442 cbc->Transform(d); |
|
2443 } |
|
2444 |
|
2445 if (aAddPadding) |
|
2446 { |
|
2447 padding = KEncryptionKeySize - (dataLength - lastBlockStart); |
|
2448 aData.SetLength(lastBlockStart + KEncryptionKeySize); |
|
2449 for (i = dataLength; i < lastBlockStart + KEncryptionKeySize; i++) |
|
2450 { |
|
2451 aData[i] = padding; |
|
2452 } |
|
2453 d.Set(aData.MidTPtr (lastBlockStart, KEncryptionKeySize)); |
|
2454 cbc->Transform(d); |
|
2455 } |
|
2456 CleanupStack::PopAndDestroy(); // cbc |
|
2457 } |
|
2458 |
|
2459 // ----------------------------------------------------------------------------- |
|
2460 // CDRMRightsDB::DecryptL |
|
2461 // Decrypt data and return it to the caller, using the CEK for this session |
|
2462 // ----------------------------------------------------------------------------- |
|
2463 // |
|
2464 void CDRMRightsDB::DecryptL( const TDesC8& aIv, |
|
2465 TPtr8& aData, |
|
2466 TBool aRemovePadding, |
|
2467 const TDesC8& aEncryptionKey ) |
|
2468 { |
|
2469 CAESDecryptor* aes = NULL; |
|
2470 CModeCBCDecryptor* cbc = NULL; |
|
2471 TInt i; |
|
2472 TInt n; |
|
2473 TPtr8 d(NULL, 0); |
|
2474 |
|
2475 if (iKey->Length() > 0) |
|
2476 { |
|
2477 aes = CAESDecryptor::NewLC( aEncryptionKey ); |
|
2478 cbc = CModeCBCDecryptor::NewLC(aes, aIv); |
|
2479 CleanupStack::Pop(); // aes, now owned by cbc |
|
2480 |
|
2481 for (i = 0; i < aData.Length(); i += KEncryptionKeySize ) |
|
2482 { |
|
2483 d.Set(aData.MidTPtr (i, KEncryptionKeySize)); |
|
2484 cbc->Transform(d); |
|
2485 } |
|
2486 if (aRemovePadding) |
|
2487 { |
|
2488 n = aData.Length(); |
|
2489 aData.SetLength(n - aData[n - 1]); |
|
2490 } |
|
2491 CleanupStack::PopAndDestroy(); // cbc |
|
2492 } |
|
2493 } |
|
2494 |
|
2495 // ----------------------------------------------------------------------------- |
|
2496 // CDRMRightsDB::CheckPaddingL |
|
2497 // Check if the padding matches, aka if they key used for decryption was |
|
2498 // incorrect leave with KErrPermissionDenied |
|
2499 // ----------------------------------------------------------------------------- |
|
2500 // |
|
2501 void CDRMRightsDB::CheckPaddingL( const TDesC8& aData ) |
|
2502 { |
|
2503 TUint8 character = 0; |
|
2504 TInt limiter = 0; |
|
2505 |
|
2506 for( TInt i = 15; i >= limiter; i-- ) |
|
2507 { |
|
2508 if( i == 15 ) |
|
2509 { |
|
2510 character = aData[i]; |
|
2511 if( character < 1 || character > 16 ) |
|
2512 { |
|
2513 User::Leave( KErrPermissionDenied ); |
|
2514 } |
|
2515 limiter = 16 - character; |
|
2516 } |
|
2517 if( aData[i] != character ) |
|
2518 { |
|
2519 User::Leave( KErrPermissionDenied ); |
|
2520 } |
|
2521 } |
|
2522 }; |
|
2523 |
|
2524 // ----------------------------------------------------------------------------- |
|
2525 // CDRMRightsDB::ReadDataL |
|
2526 // Read Data from the file, if it doesn't have enough leave |
|
2527 // Error handling missing |
|
2528 // ----------------------------------------------------------------------------- |
|
2529 // |
|
2530 void CDRMRightsDB::ReadDataL( RFile& aStream, |
|
2531 TDes8& aEncIV, |
|
2532 TPtr8& aReadData, |
|
2533 HBufC8*& aDataBuffer, |
|
2534 TInt& aDataLeft, |
|
2535 TInt aSize, |
|
2536 TBool aStart, |
|
2537 const TDesC8& aEncryptionKey ) |
|
2538 { |
|
2539 TPtr8 readData(NULL, 0, 0); |
|
2540 HBufC8 *newBuffer = 0; |
|
2541 TInt bufferSize = 0; |
|
2542 TInt pos = 0; |
|
2543 TUint8* currPtr = const_cast<TUint8*>(aDataBuffer->Ptr()) + aDataBuffer->Des().MaxSize(); |
|
2544 currPtr -= aDataLeft; |
|
2545 currPtr -= KEncryptionKeySize; |
|
2546 TInt checknum = 0; |
|
2547 |
|
2548 // In the beginning read IV from the stream 1 |
|
2549 //------------------------------------------------------------------------ |
|
2550 if( aStart ) |
|
2551 { |
|
2552 readData.Set( const_cast<TUint8*>(aEncIV.Ptr()), 0, KEncryptionKeySize ); |
|
2553 User::LeaveIfError(aStream.Read( readData, KEncryptionKeySize )); |
|
2554 } |
|
2555 else |
|
2556 { |
|
2557 bufferSize = aDataBuffer->Des().MaxLength()-KEncryptionKeySize; |
|
2558 // Copy the old IV to the new IV |
|
2559 Mem::Copy( const_cast<TUint8*>( aEncIV.Ptr() ), |
|
2560 const_cast<TUint8*>( aDataBuffer->Ptr() ) + |
|
2561 bufferSize, |
|
2562 KEncryptionKeySize ); |
|
2563 } |
|
2564 |
|
2565 |
|
2566 // If the block is too small realloc: 2 |
|
2567 //------------------------------------------------------------------------ |
|
2568 bufferSize = aDataBuffer->Des().MaxLength()-KEncryptionKeySize; |
|
2569 |
|
2570 if( aSize > bufferSize) |
|
2571 { |
|
2572 bufferSize = aSize / KEncryptionKeySize; |
|
2573 bufferSize *= KEncryptionKeySize; |
|
2574 bufferSize += 2 * KEncryptionKeySize; |
|
2575 newBuffer = HBufC8::NewLC( bufferSize ); |
|
2576 } |
|
2577 |
|
2578 // calculate a proper amount of data to copy so that |
|
2579 // we stay in increments of 16 3 |
|
2580 //------------------------------------------------------------------------ |
|
2581 pos = aDataLeft; |
|
2582 |
|
2583 if( aDataLeft % KEncryptionKeySize ) |
|
2584 { |
|
2585 pos = pos - ( pos % KEncryptionKeySize ) + KEncryptionKeySize; |
|
2586 } |
|
2587 |
|
2588 |
|
2589 // Copy the existing data into the buffer 4 |
|
2590 //------------------------------------------------------------------------ |
|
2591 if( !newBuffer ) |
|
2592 { |
|
2593 Mem::Copy( const_cast<TUint8*>( aDataBuffer->Ptr() ), |
|
2594 const_cast<TUint8*>( aDataBuffer->Ptr() ) + |
|
2595 ( aDataBuffer->Des().MaxLength()-KEncryptionKeySize - pos ), |
|
2596 pos ); |
|
2597 } |
|
2598 else |
|
2599 { |
|
2600 Mem::Copy( const_cast<TUint8*>( newBuffer->Ptr() ), |
|
2601 const_cast<TUint8*>( aDataBuffer->Ptr() ) + |
|
2602 ( aDataBuffer->Des().MaxLength()-KEncryptionKeySize - pos ), |
|
2603 pos ); |
|
2604 delete aDataBuffer; |
|
2605 aDataBuffer = newBuffer; |
|
2606 } |
|
2607 |
|
2608 // Read the new data from the file 5 |
|
2609 //------------------------------------------------------------------------ |
|
2610 readData.Set( const_cast<TUint8*>( aDataBuffer->Ptr() ) + pos, 0, |
|
2611 aDataBuffer->Des().MaxLength()-KEncryptionKeySize - pos ); |
|
2612 |
|
2613 /* readData.Set( aDataBuffer->Des(). |
|
2614 MidTPtr( pos, |
|
2615 aDataBuffer->Des().MaxLength() - |
|
2616 KEncryptionKeySize - |
|
2617 pos ) ); |
|
2618 */ |
|
2619 checknum = aStream.Read( readData ); |
|
2620 User::LeaveIfError( checknum ); |
|
2621 |
|
2622 checknum = readData.Length(); |
|
2623 checknum = pos + readData.Length(); |
|
2624 checknum = aDataBuffer->Des().MaxLength(); |
|
2625 checknum = aDataBuffer->Des().MaxLength()-KEncryptionKeySize; |
|
2626 |
|
2627 // Check if we are at the final part 6 |
|
2628 //------------------------------------------------------------------------ |
|
2629 if( pos + readData.Length() != |
|
2630 aDataBuffer->Des().MaxLength()-KEncryptionKeySize ) |
|
2631 { |
|
2632 DecryptL( aEncIV, readData, ETrue, aEncryptionKey ); |
|
2633 Mem::FillZ( const_cast<TUint8*>( aEncIV.Ptr() ), KEncryptionKeySize ); |
|
2634 } |
|
2635 else |
|
2636 { |
|
2637 Mem::Copy( const_cast<TUint8*>( aDataBuffer->Ptr() ) + |
|
2638 aDataBuffer->Des().MaxLength()-KEncryptionKeySize, |
|
2639 const_cast<TUint8*>( aDataBuffer->Ptr() ) + |
|
2640 aDataBuffer->Des().MaxLength()-(KEncryptionKeySize*2), |
|
2641 KEncryptionKeySize ); |
|
2642 |
|
2643 |
|
2644 DecryptL( aEncIV, readData, EFalse, aEncryptionKey ); |
|
2645 |
|
2646 } |
|
2647 |
|
2648 // Set the buffer you read from to this: |
|
2649 aReadData.Set( const_cast<TUint8*>(aDataBuffer->Ptr()) + pos-aDataLeft, |
|
2650 readData.Length()+aDataLeft, |
|
2651 readData.Length()+aDataLeft); |
|
2652 |
|
2653 // Set the data length |
|
2654 aDataLeft = aReadData.Length(); |
|
2655 }; |
|
2656 |
|
2657 // ----------------------------------------------------------------------------- |
|
2658 // CDRMRightsDB::SetAuthenticationSeedL |
|
2659 // Set the seed in the common data |
|
2660 // ----------------------------------------------------------------------------- |
|
2661 // |
|
2662 void CDRMRightsDB::SetAuthenticationSeedL( const TDesC8& aContentId, |
|
2663 const TDesC8& aSeed ) |
|
2664 { |
|
2665 TFileName path; |
|
2666 TInt error = KErrNone; |
|
2667 CDRMRightsData* rights = NULL; |
|
2668 CDRMCommonData* data = NULL; |
|
2669 |
|
2670 GetRightsFileNameL( aContentId, path); |
|
2671 |
|
2672 TRAP( error, rights = CDRMRightsData::OpenL( path, iFileServer ) ); |
|
2673 if( rights ) |
|
2674 { |
|
2675 CleanupStack::PushL( rights ); |
|
2676 } |
|
2677 else |
|
2678 { |
|
2679 User::Leave( error ); |
|
2680 } |
|
2681 |
|
2682 data = const_cast<CDRMCommonData*>(rights->GetCommonDataL()); |
|
2683 |
|
2684 data->SetAuthenticationSeedL( aSeed ); |
|
2685 |
|
2686 rights->UpdateCommonDataL( data ); |
|
2687 |
|
2688 CleanupStack::PopAndDestroy(); // rights |
|
2689 } |
|
2690 |
|
2691 // ----------------------------------------------------------------------------- |
|
2692 // CDRMRightsDB::GetAuthenticationSeedL |
|
2693 // Get the seed from the common data |
|
2694 // ----------------------------------------------------------------------------- |
|
2695 // |
|
2696 HBufC8* CDRMRightsDB::GetAuthenticationSeedL( const TDesC8& aContentId ) |
|
2697 { |
|
2698 TFileName path; |
|
2699 CDRMRightsData* rights( NULL ); |
|
2700 HBufC8* seed( NULL ); |
|
2701 |
|
2702 GetRightsFileNameL( aContentId, path ); |
|
2703 |
|
2704 rights = CDRMRightsData::OpenL( path, iFileServer ); |
|
2705 CleanupStack::PushL( rights ); |
|
2706 |
|
2707 seed = const_cast< CDRMCommonData* >( rights->GetCommonDataL() ) |
|
2708 ->AuthenticationSeed().AllocL(); |
|
2709 |
|
2710 CleanupStack::PopAndDestroy(); // rights |
|
2711 |
|
2712 return seed; |
|
2713 } |
|
2714 |
|
2715 // ----------------------------------------------------------------------------- |
|
2716 // CDRMRightsDB::Updating |
|
2717 // Return the iLastUpdate flag. Updating is considered as something that happens |
|
2718 // in a specific time window, to acknowledge the fact that e.g. events which are |
|
2719 // tiggered in the updating process come a bit later through the active |
|
2720 // scheduled. |
|
2721 // ----------------------------------------------------------------------------- |
|
2722 // |
|
2723 TBool CDRMRightsDB::Updating() |
|
2724 { |
|
2725 TTime now; |
|
2726 TBool r = EFalse; |
|
2727 TTimeIntervalMicroSeconds interval; |
|
2728 |
|
2729 now.HomeTime(); |
|
2730 interval = now.MicroSecondsFrom( iLastUpdate ); |
|
2731 |
|
2732 #ifdef _LOGGING |
|
2733 TBuf<256> logBuffer; |
|
2734 logBuffer.AppendNum( interval.Int64() ); |
|
2735 DRMLOG( _L(" CDRMRightsDB::Updating: Update interval: " ) ); |
|
2736 DRMLOG( logBuffer ); |
|
2737 #endif |
|
2738 |
|
2739 if ( interval < KMaxUpdateTime ) |
|
2740 { |
|
2741 r = ETrue; |
|
2742 } |
|
2743 return r; |
|
2744 } |
|
2745 |
|
2746 // ----------------------------------------------------------------------------- |
|
2747 // CDRMRightsDB::MarkAsCorrupted |
|
2748 // Mark the DB as corrupted by creating a specific file in the RDB structure. If |
|
2749 // that file is detected, the RDB gets recreated. |
|
2750 // ----------------------------------------------------------------------------- |
|
2751 // |
|
2752 void CDRMRightsDB::MarkAsCorrupted() |
|
2753 { |
|
2754 TFileName name; |
|
2755 RFile file; |
|
2756 |
|
2757 name.Copy( *iDbPath ); |
|
2758 name.Append( KCorruptionFlagFile ); |
|
2759 file.Create( iFileServer, name, EFileWrite ); |
|
2760 file.Close(); |
|
2761 } |
|
2762 |
|
2763 // ----------------------------------------------------------------------------- |
|
2764 // CDRMRightsDB::CheckCleanup |
|
2765 // Delete the db file if it's possible |
|
2766 // ----------------------------------------------------------------------------- |
|
2767 // |
|
2768 void CDRMRightsDB::CheckCleanup( const TDesC& aFileName ) |
|
2769 { |
|
2770 TInt canDelete = 0; |
|
2771 TInt error = KErrNone; |
|
2772 |
|
2773 TRAP(error, canDelete = DeleteExpiredL( aFileName, Time::NullTTime())); |
|
2774 |
|
2775 if( !error && canDelete ) |
|
2776 { |
|
2777 DRMLOG(_L("File empty, deletion allowed, deleting it:")); |
|
2778 DRMLOG( aFileName ); |
|
2779 iFileServer.Delete( aFileName ); |
|
2780 } |
|
2781 } |
|
2782 |
|
2783 |
|
2784 // End of File |