omadrm/drmengine/server/src/drmrightsdb.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     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