omadrm/drmengine/server/src/DRMDbSession.cpp
changeset 0 95b198f216e5
child 12 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "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:  This class handles all client requests.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <s32file.h>
       
    21 #include <f32file.h>
       
    22 #include <symmetric.h>
       
    23 #include <rijndael.h>
       
    24 #include <caf/caf.h>
       
    25 #include <x509keys.h>
       
    26 #include <asn1dec.h>
       
    27 #include <dcfrep.h>
       
    28 
       
    29 #include <e32math.h>
       
    30 #include <utf.h>
       
    31 
       
    32 #include <SysUtil.h>    // Disk space checking
       
    33 
       
    34 #ifdef RD_MULTIPLE_DRIVE
       
    35 #include <DriveInfo.h>
       
    36 #endif
       
    37 
       
    38 #include "Oma2Agent.h"
       
    39 #include "DRMPermission.h"
       
    40 #include "DRMDbSession.h"
       
    41 #include "drmengineclientserver.h"
       
    42 #include "DRMRightsServer.h"
       
    43 #include "RoapStorageClient.h"
       
    44 #include "OmaCrypto.h"
       
    45 #include "CmlaCrypto.h"
       
    46 #include "DrmKeyStorage.h"
       
    47 #include "drmrightsdb.h"
       
    48 #include "drmparentstorage.h"
       
    49 #include "DrmDomainContext.h"
       
    50 #include "DrmRiContext.h"
       
    51 #include "drmenginetypedefs.h"
       
    52 #include "DRMXOma.h"
       
    53 
       
    54 #include "DRMNotifier.h"
       
    55 #include "DRMEventAddRemove.h"
       
    56 #include "DRMEventModify.h"
       
    57 #include "DRMRightsCleaner.h"
       
    58 #include "DRMActiveOperation.h"
       
    59 #include "drmconsume.h"
       
    60 #include "drmlog.h"
       
    61 #include "drmpointerarray.h"
       
    62 #include "base64.h"
       
    63 
       
    64 #ifdef RD_DRM_METERING
       
    65 #include "drmmeteringdbdata.h"
       
    66 #endif
       
    67 
       
    68 // NAMESPACES
       
    69 using namespace DRMEngine;
       
    70 
       
    71 // EXTERNAL DATA STRUCTURES
       
    72 // EXTERNAL FUNCTION PROTOTYPES
       
    73 // CONSTANTS
       
    74 
       
    75 // MACROS
       
    76 #define REPLAYCACHE reinterpret_cast< CDRMRightsServer* >\
       
    77     (const_cast<CServer2*>(Server()))->ReplayCache()
       
    78 #define DRMDB ( ( CDRMRightsServer* )( Server() ) )->Database()
       
    79 #ifdef RD_DRM_METERING
       
    80 #define METERINGDB reinterpret_cast< CDRMRightsServer* >\
       
    81     (const_cast<CServer2*>(Server()))->MeteringDatabase()
       
    82 #endif
       
    83 #define RFSSESSION ( ( CDRMRightsServer* )( Server() ) )->FileServerSession()
       
    84 #define DRMNOTIFIER ( ( CDRMRightsServer* )( Server() ) )->Notifier()
       
    85 #define XOMAHEADER ( ( CDRMRightsServer* )( Server() ) )->XOmaHeaders()
       
    86 #define IMEI ( ( CDRMRightsServer* )( Server() ) )->GetIMEIL()
       
    87 #define IMSI ( ( CDRMRightsServer* )( Server() ) )->GetIMSIL()
       
    88 #define SERVER reinterpret_cast< CDRMRightsServer* >\
       
    89     (const_cast<CServer2*>(Server()))
       
    90 
       
    91 #define IPCREAD0L( a ) aMessage.ReadL( 0, a )
       
    92 #define IPCREAD1L( a ) aMessage.ReadL( 1, a )
       
    93 #define IPCREAD2L( a ) aMessage.ReadL( 2, a )
       
    94 #define IPCREAD3L( a ) aMessage.ReadL( 3, a )
       
    95 #define IPCWRITE0L( a ) aMessage.WriteL( 0, a )
       
    96 #define IPCWRITE1L( a ) aMessage.WriteL( 1, a )
       
    97 #define IPCWRITE2L( a ) aMessage.WriteL( 2, a )
       
    98 #define IPCWRITE3L( a ) aMessage.WriteL( 3, a )
       
    99 #define IPCGETDESLEN0 aMessage.GetDesLength( 0 )
       
   100 #define IPCGETDESLEN1 aMessage.GetDesLength( 1 )
       
   101 #define IPCGETDESLEN2 aMessage.GetDesLength( 2 )
       
   102 #define IPCGETDESLEN3 aMessage.GetDesLength( 3 )
       
   103 #define IPCGETDESMAXLEN0 aMessage.GetDesMaxLength( 0 )
       
   104 #define IPCGETDESMAXLEN1 aMessage.GetDesMaxLength( 1 )
       
   105 #define IPCGETDESMAXLEN2 aMessage.GetDesMaxLength( 2 )
       
   106 #define IPCGETDESMAXLEN3 aMessage.GetDesMaxLength( 3 )
       
   107 
       
   108 // LOCAL CONSTANTS AND MACROS
       
   109 
       
   110 #ifdef RD_MULTIPLE_DRIVE
       
   111 
       
   112 _LIT( KDbTempPath, "%c:\\system\\temp\\" );
       
   113 _LIT( KTimedReplayCacheFile, "%c:\\private\\101F51F2\\timererc.dat" );
       
   114 _LIT( KPlainReplayCacheFile, "%c:\\private\\101F51F2\\plainrc.dat" );
       
   115 #ifdef RD_DRM_METERING
       
   116 _LIT( KMeteringDataBaseFile, "%c:\\private\\101F51F2\\meterdb.dat" );
       
   117 #endif
       
   118 
       
   119 #else
       
   120 
       
   121 _LIT( KTimedReplayCacheFile, "c:\\private\\101F51F2\\timererc.dat" );
       
   122 _LIT( KPlainReplayCacheFile, "c:\\private\\101F51F2\\plainrc.dat" );
       
   123 #ifdef RD_DRM_METERING
       
   124 _LIT( KMeteringDataBaseFile, "c:\\private\\101F51F2\\meterdb.dat" );
       
   125 #endif
       
   126 
       
   127 #endif
       
   128 
       
   129 
       
   130 const TInt KMicrosecondsToSecond = 1000000;
       
   131 _LIT8( KFLPrefix, "flk" );
       
   132 _LIT8( KFLLongPrefix, "flk:flk" );
       
   133 
       
   134 _LIT8( KFLSuffix, "@localhost" );
       
   135 
       
   136 // These need to be updated if the DRM Filter / Oma1DcfCreator URI's change
       
   137 // IMPORTANT IMPORTANT IMPORTANT
       
   138 _LIT8( KDCMUri, "ldf:31415926535@localhost");
       
   139 _LIT8( KLDFUri, "flk:flkS60_3_0_Hutchinson_2005");
       
   140 
       
   141 _LIT8(KTimeStamp, "timeStamp");
       
   142 #ifdef RD_DRM_METERING
       
   143 _LIT8(KMeteringDelimiter, ":");
       
   144 _LIT8(KCRLF, "\r\n" );
       
   145 #endif
       
   146 
       
   147 LOCAL_C const TUint8 KFLPrefixLength = 3;
       
   148 const TUint32 KTrustedShutdownClient = 0x10205CB5;
       
   149 const TUint32 KAppInstSrv = 0x101F875A;
       
   150 
       
   151 
       
   152 const TInt KSanityDataLengthLow = 0;
       
   153 const TInt KSanityDataLengthHigh = 32768;
       
   154 
       
   155 // MODULE DATA STRUCTURES
       
   156 NONSHARABLE_STRUCT( TDeleteFile )
       
   157     {
       
   158     RFs* iFs;
       
   159     TFileName* iFileName;
       
   160     };
       
   161 
       
   162 // ============================ auto_handde helper class =======================
       
   163 //Auto handle for easening handle release on exceptional exit situations
       
   164 template<class T> class auto_handle
       
   165     {
       
   166 public:
       
   167 
       
   168     auto_handle() {}
       
   169     auto_handle(T aHandle) : iHandle( aHandle ) {}
       
   170     auto_handle( auto_handle<T>& aHandle) : iHandle( aHandle.release() ) {}
       
   171     ~auto_handle() { iHandle.Close(); }
       
   172     const T& operator()() const { return iHandle; }
       
   173     T& operator()() { return iHandle; }
       
   174     T get() const { return iHandle; }
       
   175     T release() { T temp = iHandle; iHandle = 0; return temp; }
       
   176 
       
   177 private:
       
   178     T iHandle;
       
   179     };
       
   180 
       
   181 // DATA TYPES
       
   182 // LOCAL FUNCTION PROTOTYPES
       
   183 LOCAL_C void DeleteFile( TAny* aHandle );
       
   184 LOCAL_C void DeleteObject( TAny* aObject );
       
   185 LOCAL_C TTime EndTime( const TTime& aTime1, const TTime& aTime2 );
       
   186 
       
   187 // FORWARD DECLARATIONS
       
   188 LOCAL_C void ModifyRightsObjectByTimeL( CDRMPermission* aRights,
       
   189                                         TTimeIntervalMicroSeconds& aChange,
       
   190                                         TBool aModifyInsertionTime );
       
   191 LOCAL_C void ModifyTimesInListL( CDRMPermissionList* aList,
       
   192                                  TTimeIntervalMicroSeconds& aChange,
       
   193                                  TBool aModifyInsertionTime );
       
   194 
       
   195 LOCAL_C void ModifyConstraintByTime( CDRMConstraint* aConstraint,
       
   196                                      TTimeIntervalMicroSeconds& aChange );
       
   197 
       
   198 LOCAL_C TPtrC8 ExtractElement( const TDesC8& aRights, const TDesC8& aElement,
       
   199                                TInt& aOffset );
       
   200 
       
   201 LOCAL_C TTime Iso8601ToTime( TDesC8& aTimeString );
       
   202 
       
   203 // ============================= LOCAL FUNCTIONS ==============================
       
   204 
       
   205 // -----------------------------------------------------------------------------
       
   206 // SanitizeL
       
   207 // Performs a sanity check on length parameters
       
   208 // -----------------------------------------------------------------------------
       
   209 //
       
   210 LOCAL_C void SanitizeL( TInt aParam )
       
   211     {
       
   212     if( aParam <= KSanityDataLengthLow || aParam > KSanityDataLengthHigh )
       
   213         {
       
   214         User::Leave(KErrArgument);
       
   215         }
       
   216     }
       
   217 
       
   218 
       
   219 LOCAL_C void ModifyTimesInListL( CDRMPermissionList* aList,
       
   220     TTimeIntervalMicroSeconds& aChange,
       
   221     TBool aModifyInsertionTime )
       
   222     {
       
   223     TInt i = 0;
       
   224 
       
   225     // Go through the whole list and run the modification for all objects
       
   226     for( i = 0; i < aList->Count(); i++ )
       
   227         {
       
   228         // Call modification for each rights object in the list
       
   229         ModifyRightsObjectByTimeL( (*aList)[i], aChange, aModifyInsertionTime );
       
   230         }
       
   231     };
       
   232 
       
   233 LOCAL_C void ModifyRightsObjectByTimeL( CDRMPermission* aRights,
       
   234     TTimeIntervalMicroSeconds& aChange,
       
   235     TBool aModifyInsertionTime )
       
   236     {
       
   237 
       
   238     // If original insertion time exists and we want to change it, change it
       
   239     if ( aModifyInsertionTime && aRights->iOriginalInsertTime != Time::NullTTime() )
       
   240         {
       
   241         aRights->iOriginalInsertTime += aChange;
       
   242         }
       
   243 
       
   244     if ( aRights->iAvailableRights & ERightsTopLevel )
       
   245         {
       
   246         ModifyConstraintByTime( aRights->iTopLevel, aChange );
       
   247         }
       
   248 
       
   249     // If play rights are available, check if they need to be changed
       
   250     if ( aRights->iAvailableRights & ERightsPlay )
       
   251         {
       
   252         ModifyConstraintByTime( aRights->iPlay, aChange );
       
   253         }
       
   254 
       
   255     // If display rights are available, check if they need to be changed
       
   256     if ( aRights->iAvailableRights & ERightsDisplay )
       
   257         {
       
   258         ModifyConstraintByTime( aRights->iDisplay, aChange );
       
   259         }
       
   260 
       
   261     // If execute rights are available, check if they need to be changed
       
   262     if ( aRights->iAvailableRights & ERightsExecute )
       
   263         {
       
   264         ModifyConstraintByTime( aRights->iExecute, aChange );
       
   265         }
       
   266 
       
   267     // If print rights are available, check if they need to be changed
       
   268     if ( aRights->iAvailableRights & ERightsPrint )
       
   269         {
       
   270         ModifyConstraintByTime( aRights->iPrint, aChange );
       
   271         }
       
   272 
       
   273     };
       
   274 
       
   275 LOCAL_C void ModifyConstraintByTime(
       
   276     CDRMConstraint* aConstraint,
       
   277     TTimeIntervalMicroSeconds& aChange )
       
   278     {
       
   279     // if start time exists, modify it
       
   280     if ( aConstraint->iActiveConstraints & EConstraintStartTime )
       
   281         {
       
   282         aConstraint->iStartTime += aChange;
       
   283         }
       
   284 
       
   285     // if end time exists, modify it
       
   286     if ( aConstraint->iActiveConstraints & EConstraintEndTime )
       
   287         {
       
   288         aConstraint->iEndTime += aChange;
       
   289         }
       
   290 
       
   291     // if activated interval exists, modify it
       
   292     if ( aConstraint->iActiveConstraints & EConstraintInterval &&
       
   293          aConstraint->iIntervalStart != Time::NullTTime() )
       
   294         {
       
   295         aConstraint->iIntervalStart += aChange;
       
   296         }
       
   297     };
       
   298 
       
   299 LOCAL_C TPtrC8 ExtractElement( const TDesC8& aRights,
       
   300                                const TDesC8& aElement,
       
   301                                TInt& aOffset )
       
   302     {
       
   303     DRMLOG( _L("CDRMDbSession::ExtractElement") );
       
   304 
       
   305     TPtrC8 temp( KNullDesC8 );
       
   306     TInt startPos = ( 0 );
       
   307     TInt endPos = ( 0 );
       
   308     TInt ret( 0 );
       
   309     TInt startLength ( 0 );
       
   310 
       
   311     auto_handle< RBuf8 > tagToBeFound;
       
   312     // Must be nonleaving since this function is nonleaving
       
   313     ret = tagToBeFound().Create( aElement.Length() + 3 ); // max "</" aElement ">"
       
   314     if ( ret != KErrNone )
       
   315         {
       
   316         aOffset = -1;
       
   317         return KNullDesC8();
       
   318         }
       
   319 
       
   320     // First we try to find the start tag (as localname)
       
   321     tagToBeFound().SetLength( 0 );
       
   322     tagToBeFound().AppendFormat( _L8( "<%S" ), &aElement );
       
   323 
       
   324     temp.Set( aRights.Mid( aOffset ) );
       
   325 
       
   326     startPos = temp.Find( tagToBeFound() );
       
   327 
       
   328     startLength = tagToBeFound().Length();
       
   329     startPos += aOffset;
       
   330     temp.Set( aRights.Mid( startPos + startLength ) );
       
   331 
       
   332     // Now find the end of the start tag
       
   333     tagToBeFound().SetLength( 0 );
       
   334     tagToBeFound().Append( _L8( ">" ) ); // '>' as last
       
   335 
       
   336     // Define the starting point of the data after the start tag
       
   337     // and skip the '>' mark.
       
   338     startPos = startPos + startLength + temp.Find( tagToBeFound() ) + 1;
       
   339 
       
   340     temp.Set( aRights.Mid( startPos ) );
       
   341 
       
   342     // Finally find the start of the end tag
       
   343     tagToBeFound().SetLength( 0 );
       
   344     tagToBeFound().AppendFormat( _L8( "</%S" ), &aElement );
       
   345 
       
   346     endPos = startPos + temp.Find(tagToBeFound() );
       
   347 
       
   348     if ( endPos < startPos )
       
   349         {
       
   350         aOffset = -1;
       
   351         return KNullDesC8();
       
   352         }
       
   353 
       
   354     temp.Set( aRights.Mid(startPos, endPos - startPos) );
       
   355 
       
   356     aOffset = endPos;
       
   357     DRMLOG2( _L( "Calculated length %d" ), endPos - startPos);
       
   358     DRMLOG( _L( "Extracted element" ) );
       
   359 
       
   360     //auto_handle closes and frees allocated resources
       
   361     return temp;
       
   362     };
       
   363 
       
   364 LOCAL_C TTime Iso8601ToTime( TDesC8& aTimeString )
       
   365     {
       
   366 
       
   367     DRMLOG( _L("CDRMDbSession::Iso8601ToTime") );
       
   368 
       
   369     TLex8 lex;
       
   370     TInt year = 0;
       
   371     TInt month = 0;
       
   372     TInt day = 0;
       
   373     TInt hour = 0;
       
   374     TInt minute = 0;
       
   375     TInt second = 0;
       
   376     TTime r = Time::NullTTime();
       
   377     TLocale l;
       
   378     TTimeIntervalSeconds offset(l.UniversalTimeOffset());
       
   379 
       
   380     if (aTimeString.Length() > 0)
       
   381         {
       
   382         lex = aTimeString;
       
   383         lex.Val(year);
       
   384         lex.Inc();
       
   385         lex.Val(month);
       
   386         lex.Inc();
       
   387         lex.Val(day);
       
   388         lex.Inc();
       
   389         lex.Val(hour);
       
   390         lex.Inc();
       
   391         lex.Val(minute);
       
   392         lex.Inc();
       
   393         lex.Val(second);
       
   394         r = TTime(TDateTime(year, static_cast<TMonth>(month - 1), day - 1,
       
   395                 hour, minute, second, 0));
       
   396         if (lex.Get() != 'Z')
       
   397             {
       
   398             r += offset;
       
   399             }
       
   400         }
       
   401     return r;
       
   402     }
       
   403 
       
   404 #ifdef RD_DRM_METERING
       
   405 LOCAL_C HBufC8* CreateMeteringDataL( CDRMPointerArray<CDrmMeteringDbData>* meteringArray )
       
   406     {
       
   407     // Calculate buffer size of cipher data
       
   408     TInt size( sizeof( KCRLF ) );
       
   409     HBufC8* cipherData = NULL;
       
   410     TPtr8 ptr( NULL, 0 );
       
   411 
       
   412     _LIT8( KElementStart, "<rawMeteringReportData>");
       
   413     _LIT8( KElementEnd, "</rawMeteringReportData>");
       
   414 
       
   415     size = KElementStart().Size() + KElementEnd().Size();
       
   416 
       
   417     for( TUint i(0); i < meteringArray->Count(); i++ )
       
   418         {
       
   419         size += sizeof( ( *meteringArray)[i]->iContentId );
       
   420         if ( (*meteringArray)[i]->iParentUid &&
       
   421              (*meteringArray)[i]->iParentUid->Size() )
       
   422             {
       
   423             size += (*meteringArray)[i]->iParentUid->Size() + 1;
       
   424             }
       
   425         switch( (*meteringArray)[i]->iPermission )
       
   426             {
       
   427             case EPlay:
       
   428                 size += 4;
       
   429                 break;
       
   430             case EView:
       
   431             case EExecute:
       
   432                 size += 7;
       
   433                 break;
       
   434             case EPrint:
       
   435                 size+= 5;
       
   436                 break;
       
   437             default:
       
   438                 break; // Not a valid permission
       
   439             }
       
   440         size += (*meteringArray)[i]->iContentId->Size();
       
   441         size += sizeof( (*meteringArray)[i]->iAccumulatedTime.Int() / 60 );
       
   442         size += sizeof( (*meteringArray)[i]->iAccumulatedTime.Int() % 60 );
       
   443         if( ( ( *meteringArray)[i]->iAccumulatedTime.Int() % 60 ) < 10 )
       
   444             {
       
   445             size++; //for precending zero for seconds..
       
   446             }
       
   447         size += sizeof( ( *meteringArray)[i]->iCount );
       
   448         size += 4 * sizeof( KMeteringDelimiter ); // ":" -delimiter
       
   449         size += sizeof( KCRLF );
       
   450         }
       
   451 
       
   452     cipherData = HBufC8::NewLC( size );
       
   453     ptr.Set( cipherData->Des() );
       
   454     ptr.Append( KElementStart );
       
   455 
       
   456     for( TUint i(0); i < meteringArray->Count(); i++ )
       
   457         {
       
   458         ptr.Append( KCRLF );
       
   459         if ( (*meteringArray)[i]->iParentUid &&
       
   460              (*meteringArray)[i]->iParentUid->Size() )
       
   461             {
       
   462             ptr.Append( *(*meteringArray)[i]->iParentUid );
       
   463             ptr.Append( _L(";") );
       
   464             }
       
   465         ptr.Append( *(*meteringArray)[i]->iContentId );
       
   466         ptr.Append( KMeteringDelimiter );
       
   467         switch( (*meteringArray)[i]->iPermission )
       
   468             {
       
   469             case EPlay:
       
   470                 ptr.Append( _L("play") );
       
   471                 break;
       
   472             case EView:
       
   473                 ptr.Append( _L("display") );
       
   474                 break;
       
   475             case EExecute:
       
   476                 ptr.Append( _L("execute") );
       
   477                 break;
       
   478             case EPrint:
       
   479                 ptr.Append( _L("print") );
       
   480                 break;
       
   481             default:
       
   482                 break; // Not a valid permission
       
   483             }          // export not supported
       
   484         ptr.Append( KMeteringDelimiter );
       
   485         ptr.AppendNum( (*meteringArray)[i]->iCount );
       
   486         ptr.Append( KMeteringDelimiter );
       
   487         ptr.AppendNum( (*meteringArray)[i]->iAccumulatedTime.Int() / 60 );
       
   488         ptr.Append( KMeteringDelimiter );
       
   489         if( ( ( *meteringArray)[i]->iAccumulatedTime.Int() % 60 ) < 10 )
       
   490             {
       
   491             ptr.AppendNum( 0 ); //precending zero for seconds..
       
   492             }
       
   493         ptr.AppendNum( (*meteringArray)[i]->iAccumulatedTime.Int() % 60 );
       
   494         }
       
   495     ptr.Append( KCRLF );
       
   496     ptr.Append( KElementEnd );
       
   497     CleanupStack::Pop( cipherData );
       
   498     return cipherData;
       
   499     }
       
   500 #endif
       
   501 
       
   502 // ----------------------------------------------------------------------------
       
   503 // DeleteFile
       
   504 // Deletes the file by TFileName presented by aHandle
       
   505 // ----------------------------------------------------------------------------
       
   506 //
       
   507 void DeleteFile( TAny* aHandle )
       
   508     {
       
   509     __ASSERT_DEBUG( aHandle, User::Panic( _L( "DeleteFile" ), KErrArgument ) );
       
   510     TDeleteFile* handle = reinterpret_cast< TDeleteFile* >( aHandle );
       
   511 
       
   512     handle->iFs->Delete( *( handle->iFileName ) );
       
   513     }
       
   514 
       
   515 // ----------------------------------------------------------------------------
       
   516 // DeleteObject
       
   517 // Deletes the file by TFileName presented by aHandle
       
   518 // ----------------------------------------------------------------------------
       
   519 //
       
   520 void DeleteObject( TAny* aObject )
       
   521     {
       
   522     __ASSERT_DEBUG( aObject, User::Panic( _L( "DeleteObject" ), KErrArgument ) );
       
   523     MDrmKeyStorage* object = reinterpret_cast< MDrmKeyStorage* >( aObject );
       
   524     delete object;
       
   525     object = NULL;
       
   526     }
       
   527 
       
   528 
       
   529 // ----------------------------------------------------------------------------
       
   530 // EndTime
       
   531 // Calculate the true end time: pick the smaller one of aTime1 & aTime2,
       
   532 // but ignore Time::NullTTime anyhow.
       
   533 // ----------------------------------------------------------------------------
       
   534 //
       
   535 TTime EndTime( const TTime& aTime1, const TTime& aTime2 )
       
   536     {
       
   537     TTime nullTime = Time::NullTTime();
       
   538 
       
   539     if ( aTime1 == nullTime )
       
   540         {
       
   541         return aTime2;
       
   542         }
       
   543 
       
   544     if ( aTime2 == nullTime )
       
   545         {
       
   546         return aTime1;
       
   547         }
       
   548 
       
   549     return Min( aTime1, aTime2 );
       
   550     }
       
   551 
       
   552 // ============================ MEMBER FUNCTIONS ==============================
       
   553 // ----------------------------------------------------------------------------
       
   554 // CDRMRightsServer::NewLC
       
   555 // Two-phased constructor.
       
   556 // ----------------------------------------------------------------------------
       
   557 //
       
   558 CDRMDbSession* CDRMDbSession::NewL()
       
   559     {
       
   560     CDRMDbSession* self = new( ELeave ) CDRMDbSession();
       
   561 
       
   562     CleanupStack::PushL( self );
       
   563     self->ConstructL();
       
   564     CleanupStack::Pop( self );
       
   565     return self;
       
   566     }
       
   567 
       
   568 // ----------------------------------------------------------------------------
       
   569 // CDRMRightsServer::~CDRMDbSession
       
   570 // Destructor.
       
   571 // ----------------------------------------------------------------------------
       
   572 //
       
   573 CDRMDbSession::~CDRMDbSession()
       
   574     {
       
   575     DRMLOG( _L( "CDRMDbSession::~" ) );
       
   576     delete iPreparedData;
       
   577     iPreparedData = NULL;
       
   578 
       
   579     delete iWidePreparedData;
       
   580     iWidePreparedData = NULL;
       
   581 
       
   582     delete iFileName;
       
   583     iFileName = NULL;
       
   584 
       
   585     if ( iPendingRequest )
       
   586         {
       
   587         delete iPendingRequest;
       
   588         }
       
   589 
       
   590     delete iContentId;
       
   591     iContentId = NULL;
       
   592 
       
   593     iClient.Close();
       
   594 
       
   595     iCek = KNullDesC8;
       
   596     iCek.FillZ();
       
   597 
       
   598     delete iConsume;
       
   599     iRoapClient.Close();
       
   600     }
       
   601 
       
   602 // ----------------------------------------------------------------------------
       
   603 // CDRMRightsServer::CDRMDbSession
       
   604 // Default constructor.
       
   605 // ----------------------------------------------------------------------------
       
   606 //
       
   607 CDRMDbSession::CDRMDbSession():
       
   608     iCredentialsChecked(ENotChecked),
       
   609     iContentId(NULL)
       
   610     {
       
   611     iRek.SetLength( 0 );
       
   612     }
       
   613 
       
   614 
       
   615 // ----------------------------------------------------------------------------
       
   616 // CDRMDbSession::RoapClient
       
   617 // Returns a handle to the Roap client
       
   618 // ----------------------------------------------------------------------------
       
   619 Roap::RRoapStorageClient& CDRMDbSession::RoapClient()
       
   620     {
       
   621     return iRoapClient;
       
   622     }
       
   623 
       
   624 // ----------------------------------------------------------------------------
       
   625 // CDRMRightsServer::ServiceL
       
   626 // Forwards requests from clients to helper methods.
       
   627 // ----------------------------------------------------------------------------
       
   628 //
       
   629 void CDRMDbSession::ServiceL( const RMessage2& aMessage )
       
   630     {
       
   631     DRMLOG( _L( "CDRMDbSession::ServiceL" ) );
       
   632     DRMLOG2( _L( "Message Handle: %08x"), aMessage.Handle() );
       
   633 
       
   634     // Close the client before opening a new connection over it to avoid
       
   635     // leaking memory in the kernel side
       
   636     iClient.Close();
       
   637 
       
   638     aMessage.ClientL( iClient );
       
   639 
       
   640     // This function call is TRAPped by framework, and message is completed
       
   641     // with the error in case of leaving operation.
       
   642     switch ( aMessage.Function() )
       
   643         {
       
   644         case EAddRecord:
       
   645             AddRecordL( aMessage, ENoProtection );
       
   646             break;
       
   647 
       
   648         case EAddProtectedRecord:
       
   649             AddRecordL( aMessage, EPublicKey );
       
   650             break;
       
   651 
       
   652         case EAddDomainRecord:
       
   653             AddRecordL( aMessage, EDomainKey );
       
   654             break;
       
   655 
       
   656         case EGetDbEntry:
       
   657             GetRecordL( aMessage );
       
   658             break;
       
   659 
       
   660         case EGetEntryList:
       
   661             GetEntryListL( aMessage );
       
   662             break;
       
   663 
       
   664         case EDeleteWithCID:
       
   665             DeleteL( aMessage );
       
   666             break;
       
   667 
       
   668         case EDeleteRO:
       
   669             DeleteRecordL( aMessage );
       
   670             break;
       
   671 
       
   672         case EExportCIDs:
       
   673             ExportCIDsL( aMessage );
       
   674             break;
       
   675 
       
   676         case EGetKey:
       
   677             GetKeyL( aMessage );
       
   678             break;
       
   679 
       
   680         case ECheckRights:
       
   681             CheckRightsL( aMessage );
       
   682             break;
       
   683 
       
   684         case ECount:
       
   685             CountL( aMessage );
       
   686             break;
       
   687 
       
   688         case EDeleteAll:
       
   689             DeleteAllL( aMessage );
       
   690             break;
       
   691 
       
   692         case EConsume:
       
   693             ConsumeL( aMessage );
       
   694             break;
       
   695 
       
   696         case ECheckConsume:
       
   697             CheckConsumeL( aMessage );
       
   698             break;
       
   699 
       
   700         case ECalculatePadding:
       
   701             CalculatePaddingL( aMessage);
       
   702             break;
       
   703 
       
   704         case ESecureTime:
       
   705             SecureTimeL( aMessage );
       
   706             break;
       
   707 
       
   708         case EGetPreparedData:
       
   709             GetPreparedDataL( aMessage );
       
   710             break;
       
   711 
       
   712         case EAddDomainRO:
       
   713             AddDomainROL( aMessage );
       
   714             break;
       
   715 
       
   716         case EGetDomainRO:
       
   717             GetDomainROL( aMessage );
       
   718             break;
       
   719 
       
   720         case EDeleteDomainRO:
       
   721             DeleteDomainROL( aMessage );
       
   722             break;
       
   723 
       
   724         case EIsInCache:
       
   725             IsInCacheL( aMessage );
       
   726             break;
       
   727 
       
   728         case EAddToCache:
       
   729             AddToCacheL( aMessage );
       
   730             break;
       
   731 
       
   732         case EDecrypt:
       
   733             DecryptL( aMessage );
       
   734             break;
       
   735 
       
   736         case EEncrypt:
       
   737             EncryptL( aMessage );
       
   738             break;
       
   739 
       
   740         case EInitializeKey:
       
   741             InitializeKeyL( aMessage );
       
   742             break;
       
   743 
       
   744         case EInitializeGroupKey:
       
   745             InitializeGroupKeyL( aMessage );
       
   746             break;
       
   747 
       
   748         case EGetDomainRoForCid:
       
   749             GetDomainRosForCidL( aMessage );
       
   750             break;
       
   751 
       
   752         case EDeleteExpired:
       
   753             DeleteExpiredPermissionsL( aMessage );
       
   754             break;
       
   755 
       
   756         case ESetEstimatedArrival:
       
   757             SetEstimatedArrivalL( aMessage );
       
   758             break;
       
   759 
       
   760         case EGetEstimatedArrival:
       
   761             GetEstimatedArrivalL( aMessage );
       
   762             break;
       
   763 
       
   764         case ESetName:
       
   765             SetNameL( aMessage );
       
   766             break;
       
   767 
       
   768         case EGetName:
       
   769             GetNameL( aMessage );
       
   770             break;
       
   771 
       
   772         case EGetWideData:
       
   773             GetWideDataL( aMessage );
       
   774             break;
       
   775 
       
   776         case ECancel:
       
   777             Cancel( aMessage );
       
   778             break;
       
   779 
       
   780         case EGetUdtData:
       
   781             GetUdtDataL( aMessage );
       
   782             break;
       
   783 
       
   784         case EInitiateUdt:
       
   785             InitiateUdtL( aMessage );
       
   786             break;
       
   787 
       
   788         case EInitOrphanedList:
       
   789             InitExportOrphanedCIDsL( aMessage );
       
   790             break;
       
   791 
       
   792         case EGetOrphanedList:
       
   793             ExportOrphanedCIDsL( aMessage );
       
   794             break;
       
   795 
       
   796         case EGetFLUri:
       
   797             GetFLUriL( aMessage );
       
   798             break;
       
   799 
       
   800         case EEncodeRightsIssuerField:
       
   801             EncodeRightsIssuerL( aMessage );
       
   802             break;
       
   803 
       
   804         case EDecodeRightsIssuerField:
       
   805             DecodeRightsIssuerL( aMessage );
       
   806             break;
       
   807 
       
   808         case ESetAuthenticationSeed:
       
   809             SetAuthenticationSeedL( aMessage );
       
   810             break;
       
   811 
       
   812         case EGetAuthenticationSeed:
       
   813             GetAuthenticationSeedL( aMessage );
       
   814             break;
       
   815 
       
   816         case EVerifyMac:
       
   817             VerifyMacL( aMessage );
       
   818             break;
       
   819 
       
   820         case EGetSupportedIndividuals:
       
   821             GetSupportedIndividualsL( aMessage );
       
   822             break;
       
   823 
       
   824         case EStopWatching:
       
   825             StopWatchingL( aMessage );
       
   826             break;
       
   827 
       
   828         case EUnwrapDeviceMacAndRek:
       
   829             UnwrapMacAndRekL( aMessage, EFalse );
       
   830             break;
       
   831 
       
   832         case EUnwrapDomainMacAndRek:
       
   833             UnwrapMacAndRekL( aMessage, ETrue );
       
   834             break;
       
   835 
       
   836         case EGetRandomData:
       
   837             GetRandomDataL( aMessage );
       
   838             break;
       
   839 
       
   840         case EGetMeteringData:
       
   841             GetMeteringDataL( aMessage );
       
   842             break;
       
   843 
       
   844         case EDeleteMeteringData:
       
   845             DeleteMeteringDataL( aMessage );
       
   846             break;
       
   847 
       
   848         default:
       
   849             DRMLOG( _L( "CDRMDbSession::DispatchL: Invalid command" ) );
       
   850             User::Leave( KErrNotSupported );
       
   851         }
       
   852 
       
   853     // The message has already completed successfully.
       
   854     DRMLOG2( _L( "CDRMDbSession::ServiceL ok (%08x)"), aMessage.Handle() );
       
   855     }
       
   856 
       
   857 // ----------------------------------------------------------------------------
       
   858 // CDRMRightsServer::ServiceError
       
   859 // Completes the request with given error code if the request is still pending.
       
   860 // ----------------------------------------------------------------------------
       
   861 //
       
   862 void CDRMDbSession::ServiceError( const RMessage2& aMessage, TInt aError )
       
   863     {
       
   864     DRMLOG2( _L( "CDRMDbSession::ServiceError: error %d" ), aError );
       
   865 
       
   866     if ( !aMessage.IsNull() )
       
   867         {
       
   868         aMessage.Complete( aError );
       
   869         }
       
   870     }
       
   871 
       
   872 // -----------------------------------------------------------------------------
       
   873 // CDRMRightsServer::ConstructL
       
   874 // Second phase constructor.
       
   875 // -----------------------------------------------------------------------------
       
   876 //
       
   877 void CDRMDbSession::ConstructL()
       
   878     {
       
   879     iRoapClientConnected = EFalse;
       
   880     }
       
   881 
       
   882 // -----------------------------------------------------------------------------
       
   883 // CDRMRightsServer::AddRecord
       
   884 // Get the information from the client, construct a rights object, and add
       
   885 // it to the database.
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 void CDRMDbSession::AddRecordL(
       
   889     const RMessage2& aMessage,
       
   890     TProtectionType aProtection )
       
   891     {
       
   892     DRMLOG( _L( "CDRMDbSession::AddRecordL" ) );
       
   893     //__UHEAP_MARK;
       
   894 
       
   895     CDRMPermission* permission = NULL;
       
   896     HBufC8* wrappedcek = NULL;
       
   897     HBufC8* cek = NULL;
       
   898     HBufC8* CID = NULL;
       
   899     HBufC8* rightsData = NULL;
       
   900     TInt size = 0;
       
   901     TPtr8 data( NULL, 0 );
       
   902     TDRMUniqueID UID;
       
   903 
       
   904 
       
   905     CDRMEventAddRemove* event = CDRMEventAddRemove::NewLC( ERightsObjectRecieved );
       
   906     TRequestStatus status;
       
   907 
       
   908     SanitizeL( aMessage.GetDesLength(0) );
       
   909     SanitizeL( aMessage.GetDesLength(1) );
       
   910 
       
   911     size = User::LeaveIfError( IPCGETDESLEN1 );
       
   912     rightsData = HBufC8::NewMaxLC( size );
       
   913     data.Set( const_cast< TUint8* >( rightsData->Ptr() ), 0, size );
       
   914     IPCREAD1L( data );
       
   915     permission = CDRMPermission::NewLC();
       
   916     permission->ImportL( data );
       
   917 
       
   918     UpdateSecureTime();
       
   919 
       
   920     // Determine whether the RO is legal.
       
   921     if ( ( ( permission->iAvailableRights & ERightsPlay ) &&
       
   922            ( Invalid( *permission->iPlay ) ) ) ||
       
   923          ( ( permission->iAvailableRights & ERightsDisplay ) &&
       
   924            ( Invalid( *permission->iDisplay ) ) ) ||
       
   925          ( ( permission->iAvailableRights & ERightsExecute ) &&
       
   926            ( Invalid( *permission->iExecute ) ) ) ||
       
   927          ( ( permission->iAvailableRights & ERightsPrint ) &&
       
   928            ( Invalid( *permission->iPrint ) ) ) ||
       
   929          ( ( permission->iAvailableRights & ERightsTopLevel ) &&
       
   930            ( Invalid( *permission->iTopLevel ) ) ) )
       
   931         {
       
   932         User::Leave( ENoRights );
       
   933         }
       
   934 
       
   935     size = User::LeaveIfError( IPCGETDESLEN0 );
       
   936     CID = HBufC8::NewLC( size );
       
   937 
       
   938     size = User::LeaveIfError( IPCGETDESLEN2 );
       
   939 
       
   940     // Always reserve enough space for a key, if it's 0 then it is, length will be as well.
       
   941     size = size > KDCFKeySize ? size : KDCFKeySize;
       
   942     if( size > KSanityDataLengthHigh )
       
   943         {
       
   944         User::Leave(KErrArgument);
       
   945         }
       
   946     wrappedcek = HBufC8::NewLC( size );
       
   947 
       
   948     data.Set( CID->Des() );
       
   949     IPCREAD0L( data );
       
   950 
       
   951     data.Set( wrappedcek->Des() );
       
   952     IPCREAD2L( data );
       
   953 
       
   954 
       
   955     if ( aProtection != ENoProtection )
       
   956         {
       
   957         if(!iRek.Length())
       
   958             {
       
   959             User::Leave(KErrNotReady);
       
   960             }
       
   961 
       
   962         cek = OmaCrypto::AesUnwrapL(iRek, *wrappedcek);
       
   963         CleanupStack::PopAndDestroy( wrappedcek );
       
   964         CleanupStack::PushL( cek );
       
   965         }
       
   966     else
       
   967         {
       
   968         cek = wrappedcek;
       
   969         }
       
   970 
       
   971     DRMLOG(_L("CEK:"));
       
   972     DRMLOGHEX(( *cek ));
       
   973 
       
   974     if ( permission->iOriginalInsertTime == Time::NullTTime() )
       
   975         {
       
   976         permission->iOriginalInsertTime = iTrustedTime;
       
   977         }
       
   978 
       
   979     DRMDB.AddDBEntryL( *CID, *permission, *cek, UID );
       
   980 
       
   981     // Remove a rights object from the xoma list if it is there
       
   982     RPointerArray<CDRMXOma>& array = XOMAHEADER;
       
   983     TInt i = 0;
       
   984 
       
   985     for( ; i < array.Count(); i++ )
       
   986         {
       
   987         // if the content id is found, remove it from the list
       
   988         if( !CID->Compare( array[i]->ContentID() ) )
       
   989             {
       
   990             delete array[i];
       
   991             array.Remove( i );
       
   992             break;
       
   993             }
       
   994         }
       
   995 
       
   996     // Write the UID back to the client.
       
   997     data.Set( reinterpret_cast< TUint8* >( &UID ), sizeof( UID ),
       
   998         sizeof( UID ) );
       
   999     IPCWRITE3L( data );
       
  1000 
       
  1001     // Notify clients
       
  1002     event->SetContentIDL(CID->Des());
       
  1003 
       
  1004     DRMNOTIFIER.SendEventL(*event,status);
       
  1005     User::WaitForRequest(status);
       
  1006 
       
  1007     CleanupStack::PopAndDestroy( 5 ); // cek, CID, permission, data, event
       
  1008 
       
  1009     aMessage.Complete( KErrNone );
       
  1010 
       
  1011     //__UHEAP_MARKEND;
       
  1012     DRMLOG( _L( "CDRMDbSession::AddRecordL done" ) );
       
  1013     }
       
  1014 
       
  1015 // -----------------------------------------------------------------------------
       
  1016 // CDRMRightsServer::GetRecordL
       
  1017 // Get record.
       
  1018 // -----------------------------------------------------------------------------
       
  1019 //
       
  1020 void CDRMDbSession::GetRecordL( const RMessage2& aMessage )
       
  1021     {
       
  1022     DRMLOG( _L( "CDRMDbSession::GetRecordL" ) );
       
  1023 
       
  1024     CDRMPermission* object = NULL;
       
  1025     TInt size = 0;
       
  1026     TPckg< TInt > package( size );
       
  1027     TDRMUniqueID id;
       
  1028     HBufC8* CID = NULL;
       
  1029     TPtr8 data( reinterpret_cast< TUint8* >( &id ), 0, sizeof( id ) );
       
  1030 
       
  1031     // Cleanup.
       
  1032     if ( iPreparedData )
       
  1033         {
       
  1034         delete iPreparedData;
       
  1035         iPreparedData = NULL;
       
  1036         }
       
  1037 
       
  1038     IPCREAD2L( data );
       
  1039 
       
  1040     SanitizeL( aMessage.GetDesLength(3) );
       
  1041     CID = HBufC8::NewLC( IPCGETDESLEN3 );
       
  1042 
       
  1043     data.Set( CID->Des() );
       
  1044     IPCREAD3L( data );
       
  1045 
       
  1046     object = DRMDB.GetDBEntryByContentIDL( *CID, id );
       
  1047     CleanupStack::PushL( object );
       
  1048 
       
  1049     // modify the times in the rights object to UI time
       
  1050     UpdateSecureTime();
       
  1051     TTime currentTime;
       
  1052     currentTime.HomeTime();
       
  1053     TTimeIntervalMicroSeconds change = currentTime.Int64() - iTrustedTime.Int64();
       
  1054     ModifyRightsObjectByTimeL( object, change, ETrue );
       
  1055 
       
  1056     iPreparedData = object->ExportL();
       
  1057     size = iPreparedData->Length();
       
  1058 
       
  1059     IPCWRITE0L( package );
       
  1060 
       
  1061     CleanupStack::PopAndDestroy( object );
       
  1062     CleanupStack::PopAndDestroy( CID );
       
  1063 
       
  1064     aMessage.Complete( KErrNone );
       
  1065 
       
  1066     DRMLOG( _L( "CDRMDbSession::GetRecordL ok" ) );
       
  1067     }
       
  1068 
       
  1069 // -----------------------------------------------------------------------------
       
  1070 // CDRMRightsServer::GetEntryListL
       
  1071 // Create a temporary file from RPointerArray list the database created.
       
  1072 // Return the file name to the client. In case of an error, the temporary file
       
  1073 // is deleted.
       
  1074 // -----------------------------------------------------------------------------
       
  1075 //
       
  1076 void CDRMDbSession::GetEntryListL( const RMessage2& aMessage )
       
  1077     {
       
  1078     DRMLOG( _L( "CDRMDbSession::GetEntryListL" ) );
       
  1079     __UHEAP_MARK;
       
  1080 
       
  1081     TFileName tmpFile( KNullDesC );
       
  1082     HBufC8* CID = NULL;
       
  1083     TPtr8 data( NULL, 0 );
       
  1084 
       
  1085     SanitizeL( aMessage.GetDesLength(1));
       
  1086 
       
  1087     CID = HBufC8::NewLC( IPCGETDESLEN1 );
       
  1088 
       
  1089 
       
  1090     TDeleteFile dodeletefile =
       
  1091         {
       
  1092         &RFSSESSION,
       
  1093         &tmpFile
       
  1094         };
       
  1095 
       
  1096     CDRMPermissionList* list = CDRMPermissionList::NewLC();
       
  1097     list->SetAutoCleanup( ETrue );
       
  1098 
       
  1099     data.Set( CID->Des() );
       
  1100     IPCREAD1L( data );
       
  1101 
       
  1102     DRMDB.GetDBEntryByContentIDL( *CID, *list );
       
  1103 
       
  1104     // Exclude domain rights where we are not part of the domain
       
  1105     RemoveInvalidPermissionsL( list );
       
  1106     if ( list->Count() == 0 )
       
  1107         {
       
  1108         User::Leave( KErrCANoRights );
       
  1109         }
       
  1110 
       
  1111     // modify the times in the rights object to UI time
       
  1112     UpdateSecureTime();
       
  1113     TTime currentTime;
       
  1114     currentTime.HomeTime();
       
  1115     TTimeIntervalMicroSeconds change = currentTime.Int64() - iTrustedTime.Int64();
       
  1116     ModifyTimesInListL( list, change, ETrue );
       
  1117 
       
  1118     // Delete the file if something goes wrong.
       
  1119     TCleanupItem fileCleanup( DeleteFile, &dodeletefile );
       
  1120     CleanupStack::PushL( fileCleanup );
       
  1121 
       
  1122     // Convert the list to a permanent file store.
       
  1123     ListToFileL( *list, tmpFile );
       
  1124 
       
  1125     // It is virtually impossible to make WriteL to leave in this case,
       
  1126     // but anything is still possible...
       
  1127     IPCWRITE0L( tmpFile );
       
  1128 
       
  1129     CleanupStack::Pop( &dodeletefile );
       
  1130     CleanupStack::PopAndDestroy( 2 ); // list, CID
       
  1131 
       
  1132     __UHEAP_MARKEND;
       
  1133 
       
  1134     // All done
       
  1135     aMessage.Complete( KErrNone );
       
  1136 
       
  1137     DRMLOG( _L( "CDRMDbSession::GetEntryListL: ok" ) );
       
  1138     }
       
  1139 
       
  1140 // -----------------------------------------------------------------------------
       
  1141 // CDRMRightsServer::DeleteL
       
  1142 // Delete all rights objects with a certain CID.
       
  1143 // -----------------------------------------------------------------------------
       
  1144 //
       
  1145 void CDRMDbSession::DeleteL( const RMessage2& aMessage )
       
  1146     {
       
  1147     DRMLOG( _L( "CDRMDbSession::DeleteL" ) );
       
  1148     __UHEAP_MARK;
       
  1149     TPtr8 data( NULL, 0 );
       
  1150 
       
  1151     // Check for VendorId
       
  1152 
       
  1153     _LIT_SECURITY_POLICY_V0(vidCheck, VID_DEFAULT); // Check Default VID
       
  1154     if ( !vidCheck().CheckPolicy(iClient) )
       
  1155         {
       
  1156         User::Leave( KErrAccessDenied );
       
  1157         }
       
  1158 
       
  1159     CDRMEventAddRemove* event = CDRMEventAddRemove::NewLC( ERightsObjectDeletedAll );
       
  1160     TRequestStatus status;
       
  1161 
       
  1162     HBufC8* CID = HBufC8::NewLC(
       
  1163         User::LeaveIfError( IPCGETDESLEN2 ) );
       
  1164 
       
  1165     data.Set( CID->Des() );
       
  1166 
       
  1167     IPCREAD2L( data );
       
  1168 
       
  1169 
       
  1170     // Check if deletion is allowed:
       
  1171     if( DeleteAllowedL( *CID ) )
       
  1172         {
       
  1173         DRMDB.DeleteDBEntryL( *CID );
       
  1174 
       
  1175         // Notify
       
  1176         event->SetContentIDL(CID->Des());
       
  1177 
       
  1178         DRMNOTIFIER.SendEventL(*event,status);
       
  1179         User::WaitForRequest(status);
       
  1180         }
       
  1181     CleanupStack::PopAndDestroy( 2 ); // CID, event
       
  1182     aMessage.Complete( KErrNone );
       
  1183     __UHEAP_MARKEND;
       
  1184     DRMLOG( _L( "CDRMDbSession::DeleteL ok" ) );
       
  1185     }
       
  1186 
       
  1187 // -----------------------------------------------------------------------------
       
  1188 // CDRMRightsServer::DeleteRecordL
       
  1189 // Delete a single RO.
       
  1190 // -----------------------------------------------------------------------------
       
  1191 //
       
  1192 void CDRMDbSession::DeleteRecordL( const RMessage2& aMessage )
       
  1193     {
       
  1194     DRMLOG( _L( "CDRMDbSession::DeleteRecordL" ) );
       
  1195     __UHEAP_MARK;
       
  1196     TDRMUniqueID id;
       
  1197 
       
  1198     _LIT_SECURITY_POLICY_V0(vidCheck, VID_DEFAULT); // Check Default VID
       
  1199     if ( !vidCheck().CheckPolicy(iClient) )
       
  1200         {
       
  1201         User::Leave( KErrAccessDenied );
       
  1202         }
       
  1203 
       
  1204     CDRMEventAddRemove* event = CDRMEventAddRemove::NewLC( ERightsObjectDeleted );
       
  1205     TRequestStatus status;
       
  1206 
       
  1207     TPtr8 data(
       
  1208         reinterpret_cast< TUint8* >( &id ), 0, sizeof( TDRMUniqueID ) );
       
  1209 
       
  1210     HBufC8* CID = HBufC8::NewLC(
       
  1211         User::LeaveIfError( IPCGETDESLEN3 ) );
       
  1212 
       
  1213     IPCREAD0L( data );
       
  1214 
       
  1215     data.Set( CID->Des() );
       
  1216     IPCREAD3L( data );
       
  1217 
       
  1218     // Check if deletion is allowed:
       
  1219     if( DeleteAllowedL( *CID ) )
       
  1220         {
       
  1221         DRMDB.DeleteDBEntryL( *CID, id );
       
  1222 
       
  1223         event->SetContentIDL( CID->Des() );
       
  1224 
       
  1225         DRMNOTIFIER.SendEventL( *event, status );
       
  1226         User::WaitForRequest( status );
       
  1227         }
       
  1228 
       
  1229     CleanupStack::PopAndDestroy( 2 ); // CID, event
       
  1230 
       
  1231     aMessage.Complete( KErrNone );
       
  1232     __UHEAP_MARKEND;
       
  1233     DRMLOG( _L( "CDRMDbSession::DeleteRecordL ok" ) );
       
  1234     }
       
  1235 
       
  1236 // -----------------------------------------------------------------------------
       
  1237 // CDRMRightsServer::ExportCIDsL
       
  1238 // Create a temporary file for rights database to export the CIDs,
       
  1239 // and write the file name to the client.
       
  1240 // -----------------------------------------------------------------------------
       
  1241 //
       
  1242 void CDRMDbSession::ExportCIDsL( const RMessage2& aMessage )
       
  1243     {
       
  1244     DRMLOG( _L( "CDRMDbSession::ExportCIDsL" ) );
       
  1245     __UHEAP_MARK;
       
  1246 
       
  1247     TFileName fileName( KNullDesC );
       
  1248     TDeleteFile deletefile =
       
  1249         {
       
  1250         &RFSSESSION,
       
  1251         &fileName
       
  1252         };
       
  1253 
       
  1254     TCleanupItem item( DeleteFile, &deletefile );
       
  1255     CleanupStack::PushL( item );
       
  1256 
       
  1257     DRMDB.ExportContentIDListL( fileName );
       
  1258 
       
  1259     IPCWRITE0L( fileName );
       
  1260 
       
  1261     CleanupStack::Pop( &deletefile );
       
  1262 
       
  1263     aMessage.Complete( KErrNone );
       
  1264     __UHEAP_MARKEND;
       
  1265     DRMLOG( _L( "CDRMDbSession::ExportCIDsL: ok" ) );
       
  1266     }
       
  1267 
       
  1268 // -----------------------------------------------------------------------------
       
  1269 // CDRMRightsServer::GetKeyL
       
  1270 // Ask for a list of rights object based on the given CID.
       
  1271 // If there is even one rights object which allows the required consuming
       
  1272 // operation, get the key from database updating the RO if necessary.
       
  1273 // -----------------------------------------------------------------------------
       
  1274 //
       
  1275 void CDRMDbSession::GetKeyL( const RMessage2& aMessage )
       
  1276     {
       
  1277     DRMLOG( _L( "CDRMDbSession::GetKeyL" ) );
       
  1278     __UHEAP_MARK;
       
  1279     // If credentials haven't been checked, don't return the key
       
  1280     if (iCredentialsChecked == ECheckedAndAllowed)
       
  1281         {
       
  1282         if (iCek.Length() > 0)
       
  1283             {
       
  1284             aMessage.Write(2, iCek);
       
  1285             aMessage.Complete(KErrNone);
       
  1286             }
       
  1287         else
       
  1288             {
       
  1289             aMessage.Complete(KErrCANoRights);
       
  1290             }
       
  1291         }
       
  1292     else
       
  1293         {
       
  1294         aMessage.Complete(KErrAccessDenied);
       
  1295         }
       
  1296     __UHEAP_MARKEND;
       
  1297     DRMLOG( _L( "CDRMDbSession::GetKeyL: Ok" ) );
       
  1298     }
       
  1299 
       
  1300 // -----------------------------------------------------------------------------
       
  1301 // CDRMRightsServer::CheckRightsL
       
  1302 // Check if there are sufficient rights at the moment. Nothing is changed from
       
  1303 // the database.
       
  1304 // -----------------------------------------------------------------------------
       
  1305 //
       
  1306 void CDRMDbSession::CheckRightsL( const RMessage2& aMessage )
       
  1307     {
       
  1308     DRMLOG( _L( "CDRMDbSession::CheckRightsL" ) );
       
  1309     TIntent intent;
       
  1310     TInt length = 0;
       
  1311     CDRMPermission* child = NULL;
       
  1312     HBufC8* cid = NULL;
       
  1313     HBufC8* buffer = NULL;
       
  1314     TPtr8 tmp( NULL, 0, 0 );
       
  1315     TInt r = KErrNone;
       
  1316     TInt size = 0;
       
  1317     TPckg<TInt> package( size );
       
  1318     TTime currentTime;
       
  1319     TTimeIntervalMicroSeconds change;
       
  1320     TUint32 reason = 0;
       
  1321     TPckg<TUint32> package2( reason );
       
  1322     TInt error = KErrNone;
       
  1323     HBufC8* uri = NULL;
       
  1324 
       
  1325     delete iPreparedData;
       
  1326     iPreparedData = NULL;
       
  1327     intent = static_cast<TIntent>( aMessage.Int0() );
       
  1328     DRMLOG2(_L("Intent: %d"), intent);
       
  1329 
       
  1330     if ( intent == EPlay || intent == EView ||
       
  1331          intent == EExecute || intent == EPrint || intent == EUnknown )
       
  1332         {
       
  1333         length = User::LeaveIfError( aMessage.GetDesLength( 1 ) );
       
  1334         cid = HBufC8::NewLC( length );
       
  1335         tmp.Set( cid->Des() );
       
  1336         aMessage.ReadL( 1, tmp );
       
  1337         DRMLOG(_L("CID:"));
       
  1338         DRMLOGHEX(tmp);
       
  1339         error = FindRightsObject( intent, *cid, child, uri, reason );
       
  1340         delete uri;
       
  1341         uri = NULL; // URI not used anywhere
       
  1342 
       
  1343         // if an error occurs we still need to write the information to the client,
       
  1344         // but then we can leave
       
  1345         if( error )
       
  1346             {
       
  1347             aMessage.WriteL( 3, package2 );
       
  1348             User::Leave( error );
       
  1349             }
       
  1350 
       
  1351         CleanupStack::PopAndDestroy( cid );
       
  1352         CleanupStack::PushL( child );
       
  1353         }
       
  1354     else if ( intent == EInstall || intent == EPeek )
       
  1355         {
       
  1356         length = User::LeaveIfError( aMessage.GetDesLength( 1 ) );
       
  1357         cid = HBufC8::NewLC( length );
       
  1358         tmp.Set( cid->Des() );
       
  1359         aMessage.ReadL( 1, tmp );
       
  1360         DRMLOG(_L("CID:"));
       
  1361         DRMLOGHEX(tmp);
       
  1362 
       
  1363         // If we have the key, install and peek always have full rights
       
  1364         buffer = DRMDB.GetDecryptionKeyL( *cid );
       
  1365         CleanupStack::PopAndDestroy( cid );
       
  1366 
       
  1367         if ( buffer )
       
  1368             {
       
  1369             delete buffer;
       
  1370             child = CDRMPermission::NewL();
       
  1371             CleanupStack::PushL( child );
       
  1372             child->iAvailableRights = ERightsAll;
       
  1373             }
       
  1374         else
       
  1375             {
       
  1376             r = KErrCANoRights;
       
  1377             }
       
  1378         }
       
  1379     else if ( ( intent == EPause || intent == EContinue || intent == EStop ) &&
       
  1380         iConsume )
       
  1381         {
       
  1382         // These intents only make sense if we have an ongoing session
       
  1383         child = CDRMPermission::NewL();
       
  1384         CleanupStack::PushL( child );
       
  1385         child->DuplicateL( iConsume->GetChild() );
       
  1386         }
       
  1387     else
       
  1388         {
       
  1389         r = KErrArgument;
       
  1390         }
       
  1391 
       
  1392     if ( child )
       
  1393         {
       
  1394         UpdateSecureTime();
       
  1395         currentTime.HomeTime();
       
  1396         change = currentTime.Int64() - iTrustedTime.Int64();
       
  1397         ModifyRightsObjectByTimeL( child, change, ETrue );
       
  1398         iPreparedData = child->ExportL();
       
  1399         size = iPreparedData->Length();
       
  1400         aMessage.WriteL( 2, package );
       
  1401         CleanupStack::PopAndDestroy( child );
       
  1402         }
       
  1403 
       
  1404     aMessage.Complete( r );
       
  1405 
       
  1406     DRMLOG2( _L( "CDRMDbSession::CheckRightsL: ok (%d)" ), r );
       
  1407     }
       
  1408 
       
  1409 // -----------------------------------------------------------------------------
       
  1410 // CDRMRightsServer::CountL
       
  1411 // Tell the client how many ROs there are.
       
  1412 // -----------------------------------------------------------------------------
       
  1413 //
       
  1414 void CDRMDbSession::CountL( const RMessage2& aMessage )
       
  1415     {
       
  1416     DRMLOG( _L( "CDRMDbSession::CountL" ) );
       
  1417     __UHEAP_MARK;
       
  1418     TInt count = DRMDB.GetAmountOfRightsObjectsL();
       
  1419 
       
  1420     TPtr8 data( reinterpret_cast< TUint8* >( &count ),
       
  1421                 sizeof( TInt ),
       
  1422                 sizeof( TInt ) );
       
  1423 
       
  1424     IPCWRITE0L( data );
       
  1425 
       
  1426     aMessage.Complete( KErrNone );
       
  1427     __UHEAP_MARKEND;
       
  1428     DRMLOG( _L( "CDRMDbSession::CountL: ok" ) );
       
  1429     }
       
  1430 
       
  1431 // -----------------------------------------------------------------------------
       
  1432 // CDRMRightsServer::DeleteAll
       
  1433 // Delete all ROs.
       
  1434 // -----------------------------------------------------------------------------
       
  1435 //
       
  1436 void CDRMDbSession::DeleteAllL( const RMessage2& aMessage )
       
  1437     {
       
  1438     DRMLOG( _L( "CDRMDbSession::DeleteAllL" ) );
       
  1439 
       
  1440     User::LeaveIfError( VerifyCredentials(NULL, NULL, EUnknown) );
       
  1441     if( iCredentialsChecked == ECheckedAndDenied )
       
  1442         {
       
  1443         User::Leave( KErrPermissionDenied );
       
  1444         }
       
  1445 
       
  1446     //__UHEAP_MARK;
       
  1447 
       
  1448     DRMDB.DeleteDBL();
       
  1449 
       
  1450     REPLAYCACHE.Close();
       
  1451 
       
  1452 #ifndef RD_MULTIPLE_DRIVE
       
  1453 
       
  1454     #ifdef RD_DRM_METERING
       
  1455     METERINGDB.Close();
       
  1456     RFSSESSION.Delete( KMeteringDataBaseFile );
       
  1457     METERINGDB.InitL( KMeteringDataBaseFile );
       
  1458     #endif
       
  1459 
       
  1460     RFSSESSION.Delete( KTimedReplayCacheFile );
       
  1461     RFSSESSION.Delete( KPlainReplayCacheFile );
       
  1462 
       
  1463     REPLAYCACHE.InitL( KTimedReplayCacheFile, KPlainReplayCacheFile );
       
  1464 
       
  1465 #else //RD_MULTIPLE_DRIVE
       
  1466 
       
  1467     TFileName tempPath;
       
  1468     TFileName tempPath2;
       
  1469     TInt driveNumber( -1 );
       
  1470     TChar driveLetter;
       
  1471     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
       
  1472 
       
  1473     RFSSESSION.DriveToChar( driveNumber, driveLetter );
       
  1474 
       
  1475     #ifdef RD_DRM_METERING
       
  1476     tempPath.Format( KMeteringDataBaseFile, (TUint)driveLetter );
       
  1477 
       
  1478     METERINGDB.Close();
       
  1479     RFSSESSION.Delete( tempPath );
       
  1480     METERINGDB.InitL( tempPath );
       
  1481     #endif
       
  1482 
       
  1483     tempPath.Format( KTimedReplayCacheFile, (TUint)driveLetter );
       
  1484     tempPath2.Format( KPlainReplayCacheFile, (TUint)driveLetter );
       
  1485 
       
  1486     RFSSESSION.Delete( tempPath );
       
  1487     RFSSESSION.Delete( tempPath2 );
       
  1488 
       
  1489     REPLAYCACHE.InitL( tempPath, tempPath2 );
       
  1490 
       
  1491 #endif
       
  1492 
       
  1493     if ( !iRoapClientConnected )
       
  1494         {
       
  1495         User::LeaveIfError( iRoapClient.Connect() );
       
  1496         iRoapClientConnected = ETrue;
       
  1497         }
       
  1498 
       
  1499     iRoapClient.DeleteAllL();
       
  1500 
       
  1501     aMessage.Complete( KErrNone );
       
  1502     //__UHEAP_MARKEND;
       
  1503     DRMLOG( _L( "CDRMDbSession::DeleteAllL ok" ) );
       
  1504     }
       
  1505 
       
  1506 // -----------------------------------------------------------------------------
       
  1507 // CDRMRightsServer::ListToFileL
       
  1508 // Convert the list to a file representation.
       
  1509 // -----------------------------------------------------------------------------
       
  1510 //
       
  1511 void CDRMDbSession::ListToFileL( RPointerArray< CDRMPermission >& aList,
       
  1512                                  TFileName& aFile )
       
  1513     {
       
  1514     __UHEAP_MARK;
       
  1515     DRMLOG( _L( "CDRMDbSession::ListToFileL" ) );
       
  1516 
       
  1517     TInt count( 0 );
       
  1518 
       
  1519 
       
  1520     RFileWriteStream fileStream;
       
  1521 
       
  1522 #ifndef RD_MULTIPLE_DRIVE
       
  1523 
       
  1524     User::LeaveIfError(
       
  1525         fileStream.Temp( RFSSESSION,
       
  1526                          KDRMDbTempPath,
       
  1527                          aFile,
       
  1528                          EFileWrite | EFileStream ) );
       
  1529 
       
  1530 #else //RD_MULTIPLE_DRIVE
       
  1531 
       
  1532     TInt driveNumber( -1 );
       
  1533     TChar driveLetter;
       
  1534     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
       
  1535 
       
  1536     RFSSESSION.DriveToChar( driveNumber, driveLetter );
       
  1537 
       
  1538     TFileName dbTempPath;
       
  1539     dbTempPath.Format( KDbTempPath, (TUint)driveLetter );
       
  1540 
       
  1541     User::LeaveIfError(
       
  1542       fileStream.Temp( RFSSESSION,
       
  1543                        dbTempPath,
       
  1544                        aFile,
       
  1545                        EFileWrite | EFileStream ) );
       
  1546 
       
  1547 #endif
       
  1548 
       
  1549     CleanupClosePushL( fileStream );
       
  1550 
       
  1551     TInt size( sizeof( TUint32 ) ); // streams store also other info there.
       
  1552 
       
  1553     for( count = 0; count < aList.Count(); count++ )
       
  1554         {
       
  1555         size += aList[ count ]->Size();
       
  1556         }
       
  1557 
       
  1558     // Reset count variable:
       
  1559     count = 0;
       
  1560 
       
  1561 #ifndef RD_MULTIPLE_DRIVE
       
  1562 
       
  1563     if ( SysUtil::DiskSpaceBelowCriticalLevelL( &RFSSESSION,
       
  1564                                                 size,
       
  1565                                                 EDriveC ) )
       
  1566 
       
  1567 #else //RD_MULTIPLE_DRIVE
       
  1568 
       
  1569     if ( SysUtil::DiskSpaceBelowCriticalLevelL( &RFSSESSION,
       
  1570                                                 size,
       
  1571                                                 driveNumber ) )
       
  1572 
       
  1573 #endif
       
  1574         {
       
  1575         DRMLOG( _L( "CDRMDbSession::ListToFileL: KErrDiskFull" ) );
       
  1576         User::Leave( KErrDiskFull );
       
  1577         }
       
  1578 
       
  1579     fileStream.WriteInt32L( aList.Count() );
       
  1580 
       
  1581     // Write the whole stuff into the file.
       
  1582     // URIs are ignored. No use to put them to file (always the same
       
  1583     // and the client knows it already).
       
  1584     while( count < aList.Count() )
       
  1585         {
       
  1586         aList[ count ]->ExternalizeL( fileStream );
       
  1587         ++count;
       
  1588         }
       
  1589 
       
  1590     fileStream.CommitL();
       
  1591 
       
  1592     CleanupStack::PopAndDestroy( &fileStream );
       
  1593 
       
  1594     DRMLOG( _L( "CDRMDbSession::ListToFileL: ok" ) );
       
  1595     __UHEAP_MARKEND;
       
  1596     }
       
  1597 
       
  1598 
       
  1599 // -----------------------------------------------------------------------------
       
  1600 // CDRMRightsServer::FindRightsObjectL
       
  1601 // Try to locate the best RO from the given list which allows consuming of
       
  1602 // content.
       
  1603 // If end time is defined or an interval activated, the smallest endtime
       
  1604 // is always chosen first.
       
  1605 // -----------------------------------------------------------------------------
       
  1606 //
       
  1607 void CDRMDbSession::FindRightsObjectL( TIntent aIntent,
       
  1608                                        const TDesC8& aURI,
       
  1609                                        CDRMPermission*& aChild,
       
  1610                                        HBufC8*& aUsedURI,
       
  1611                                        TUint32& aReason )
       
  1612     {
       
  1613     DRMLOG( _L( "CDRMDbSession::FindRightsObjectL" ) );
       
  1614     TInt res = KErrNotFound;
       
  1615 
       
  1616     if ( aUsedURI || aChild )
       
  1617         {
       
  1618         // Check that return parameters are null initially.
       
  1619         User::Leave( KErrArgument );
       
  1620         }
       
  1621 
       
  1622     CDRMPermissionList *perms = CDRMPermissionList::NewLC();
       
  1623     TTime time;
       
  1624 
       
  1625     perms->SetAutoCleanup( ETrue );
       
  1626     DRMDB.GetDBEntryByContentIDL( aURI , *perms );
       
  1627 
       
  1628     UpdateSecureTime();
       
  1629 
       
  1630     if ( iSecureTime )
       
  1631         {
       
  1632         time = iTrustedTime;
       
  1633         }
       
  1634     else
       
  1635         {
       
  1636         time = Time::NullTTime();
       
  1637         }
       
  1638 
       
  1639     if ( aIntent == EPeek || aIntent == EInstall )
       
  1640         {
       
  1641         // There is at least one RO available.
       
  1642         // Use any RO, whether they are valid or not.
       
  1643         // Pick the first RO in the list.
       
  1644 
       
  1645         aChild = (*perms)[0];
       
  1646         (*perms).Remove( 0 );
       
  1647 
       
  1648         CleanupStack::PopAndDestroy( perms );
       
  1649         return;
       
  1650         }
       
  1651     else if ( aIntent == EUnknown )
       
  1652         {
       
  1653         // Pick one that works, no matter what the intent is
       
  1654         for ( TInt i = 0; res == KErrNotFound && i < perms->Count(); i++ )
       
  1655             {
       
  1656             if ( (*perms)[i]->Valid( time, IMSI, aReason ) )
       
  1657                 {
       
  1658                 res = i;
       
  1659                 }
       
  1660             }
       
  1661         if ( res != KErrNotFound )
       
  1662             {
       
  1663             aChild = (*perms)[res];
       
  1664             perms->Remove( res );
       
  1665             }
       
  1666         else
       
  1667             {
       
  1668             User::Leave( KErrCANoPermission );
       
  1669             }
       
  1670         }
       
  1671     else
       
  1672         {
       
  1673         res = FindBestROsL( *perms, aURI, aIntent, aUsedURI, aReason );
       
  1674         if ( res >= 0 )
       
  1675             {
       
  1676             aChild = (*perms)[res];
       
  1677             perms->Remove( res );
       
  1678             }
       
  1679         else
       
  1680             {
       
  1681             User::Leave( KErrCANoPermission );
       
  1682             }
       
  1683         }
       
  1684     CleanupStack::PopAndDestroy( perms );
       
  1685     }
       
  1686 
       
  1687 
       
  1688 // -----------------------------------------------------------------------------
       
  1689 // CDRMRightsServer::FindRightsObject
       
  1690 // Try to locate the best RO from the given list which allows consuming of
       
  1691 // content.
       
  1692 // If end time is defined or an interval activated, the smallest endtime
       
  1693 // is always chosen first.
       
  1694 // -----------------------------------------------------------------------------
       
  1695 //
       
  1696 TInt CDRMDbSession::FindRightsObject( TIntent aIntent,
       
  1697                                       const TDesC8& aURI,
       
  1698                                       CDRMPermission*& aChild,
       
  1699                                       HBufC8*& aUsedURI,
       
  1700                                       TUint32& aReason )
       
  1701     {
       
  1702     DRMLOG( _L( "CDRMDbSession::FindRightsObject" ) );
       
  1703     TInt error = KErrNone;
       
  1704 
       
  1705     TRAP( error, FindRightsObjectL( aIntent, aURI, aChild, aUsedURI, aReason ) );
       
  1706     if ( ( error == KErrCANoRights || error == KErrCANoPermission ) &&
       
  1707         PendingRights(aURI) )
       
  1708         {
       
  1709         error = KErrCAPendingRights;
       
  1710         }
       
  1711     return error;
       
  1712     }
       
  1713 
       
  1714 // -----------------------------------------------------------------------------
       
  1715 // CDRMDbSession::CheckConsumeL
       
  1716 // Check if Consume is possible
       
  1717 // -----------------------------------------------------------------------------
       
  1718 //
       
  1719 void CDRMDbSession::CheckConsumeL( const RMessage2& aMessage )
       
  1720     {
       
  1721     DRMLOG( _L( "CDRMDbSession::CheckConsumeL" ) );
       
  1722 
       
  1723     __UHEAP_MARK;
       
  1724 
       
  1725     HBufC8* CID = NULL;
       
  1726     TPtr8 cid( NULL, 0, 0 );
       
  1727     TInt length = 0;
       
  1728     TIntent intent;
       
  1729     TUint32 reason = 0;
       
  1730 
       
  1731     length = User::LeaveIfError( IPCGETDESLEN1 );
       
  1732     CID = HBufC8::NewLC( length );
       
  1733     cid.Set( CID->Des() );
       
  1734     IPCREAD1L( cid );
       
  1735     intent = static_cast<TIntent>(aMessage.Int0());
       
  1736 
       
  1737     // Check only intents which are actually consuming something. All others
       
  1738     // always succeed, because CheckConsume is called by default when a file
       
  1739     // is opened.
       
  1740     if ( intent == EPlay || intent == EView ||
       
  1741          intent == EExecute || intent == EPrint || intent == EUnknown )
       
  1742         {
       
  1743         // Count constraints are valid for the duration of the
       
  1744         // session after they have been consumed earlier
       
  1745         if ( !( iConsume && iConsume->CountConstraintActive() ||
       
  1746                 SERVER->HasActiveCountConstraint( *CID ) ) )
       
  1747             {
       
  1748             CDRMPermission* child( NULL );
       
  1749             HBufC8* uri( NULL );
       
  1750             TInt error( FindRightsObject( intent, *CID, child, uri, reason ) );
       
  1751             delete child;
       
  1752             delete uri;
       
  1753             User::LeaveIfError( error );
       
  1754             }
       
  1755         }
       
  1756 /* Enable this code as soon as clients use EUnknown, and it is safe to fail
       
  1757    when no key is available
       
  1758     else if ( intent == EPeek || EInstall )
       
  1759         {
       
  1760         // We need at least the key for peek and install. This will leave if no
       
  1761         // key is there.
       
  1762         HBufC8* key = DRMDB.GetDecryptionKeyL( *CID );
       
  1763         delete key;
       
  1764         }
       
  1765 */
       
  1766 
       
  1767     CleanupStack::PopAndDestroy( CID );
       
  1768     aMessage.Complete( KErrNone );
       
  1769     __UHEAP_MARKEND;
       
  1770     DRMLOG( _L( "CDRMDbSession::CheckConsumeL: ok" ) );
       
  1771     }
       
  1772 
       
  1773 // -----------------------------------------------------------------------------
       
  1774 // CDRMDbSession::ConsumeL
       
  1775 // Consume the right and register the consumption.
       
  1776 // -----------------------------------------------------------------------------
       
  1777 //
       
  1778 void CDRMDbSession::ConsumeL( const RMessage2& aMessage )
       
  1779     {
       
  1780     DRMLOG( _L( "CDRMDbSession::ConsumeL" ) );
       
  1781 
       
  1782     const TIntent intent = static_cast<TIntent>(aMessage.Int0());
       
  1783     HBufC8* CID = NULL;
       
  1784     TInt length = 0;
       
  1785     TPtr8 cid( NULL, 0, 0 );
       
  1786 
       
  1787     length = User::LeaveIfError( IPCGETDESLEN1 );
       
  1788 
       
  1789     CID = HBufC8::NewLC( length );
       
  1790 
       
  1791     cid.Set( CID->Des() );
       
  1792     IPCREAD1L( cid );
       
  1793 
       
  1794     if ( intent != EUnknown )
       
  1795         {
       
  1796         if ( intent == EPeek || intent == EInstall )
       
  1797             {
       
  1798             User::LeaveIfError( VerifyCredentials( CID, NULL, intent ) );
       
  1799             }
       
  1800         else
       
  1801             {
       
  1802             if ( intent == EPlay ||
       
  1803                  intent == EView ||
       
  1804                  intent == EExecute ||
       
  1805                  intent == EPrint ||
       
  1806                  intent == EStop )
       
  1807                 {
       
  1808 
       
  1809                 if ( iConsume )
       
  1810                     {
       
  1811                     delete iConsume;
       
  1812                     iConsume = NULL;
       
  1813                     }
       
  1814                 if ( intent != EStop )
       
  1815                     {
       
  1816                     CDRMConsume* consume( NULL );
       
  1817                     consume = CDRMConsume::NewLC( *this, *CID, NULL );
       
  1818                     consume->HandleL( intent );
       
  1819                     CleanupStack::Pop( consume );
       
  1820                     iConsume = consume;
       
  1821                     }
       
  1822                 }
       
  1823             else
       
  1824                 {
       
  1825                 if ( !iConsume )
       
  1826                     {
       
  1827                     User::Leave( KErrNotReady );
       
  1828                     }
       
  1829 
       
  1830                 if ( intent == EPause )
       
  1831                     {
       
  1832                     iConsume->Pause();
       
  1833                     }
       
  1834                 else if ( intent == EContinue )
       
  1835                     {
       
  1836                     iConsume->ContinueL();
       
  1837                     }
       
  1838                 else
       
  1839                     {
       
  1840                     iConsume->Stop();
       
  1841                     }
       
  1842                 }
       
  1843             }
       
  1844         }
       
  1845     else
       
  1846         {
       
  1847         // None of the other intents are allowed here, fail
       
  1848         User::Leave( KErrArgument );
       
  1849         }
       
  1850 
       
  1851 
       
  1852     CleanupStack::PopAndDestroy( CID );
       
  1853     aMessage.Complete( KErrNone );
       
  1854     DRMLOG( _L( "CDRMDbSession::ConsumeL: ok" ) );
       
  1855     }
       
  1856 
       
  1857 // -----------------------------------------------------------------------------
       
  1858 // CDRMDbSession::CalculatePaddingL
       
  1859 //
       
  1860 // -----------------------------------------------------------------------------
       
  1861 //
       
  1862 void CDRMDbSession::CalculatePaddingL( const RMessage2& aMessage )
       
  1863     {
       
  1864     __UHEAP_MARK;
       
  1865     DRMLOG( _L( "CDRMDbSession::CalculatePaddingL" ) );
       
  1866 
       
  1867     CAESDecryptor* decryptor( NULL );
       
  1868     TInt i( 0 );
       
  1869 
       
  1870     TBuf8<KDCFKeySize * 2> data;
       
  1871     TBuf8<KDCFKeySize> iv;
       
  1872     TBuf8<KDCFKeySize> block;
       
  1873     TPtr8 tmp( NULL, 0, 0 );
       
  1874 
       
  1875     aMessage.ReadL( 0, data );
       
  1876 
       
  1877     // Check that the data we read is actually of the proper length
       
  1878     if( data.Length() != KDCFKeySize*2 )
       
  1879         {
       
  1880         User::Leave(KErrArgument);
       
  1881         }
       
  1882 
       
  1883     iv.Copy(data.Left(KDCFKeySize));
       
  1884     block.Copy(data.Right(KDCFKeySize));
       
  1885 
       
  1886     if( iCek.Length() != KDRMKeyLength )
       
  1887         {
       
  1888         User::Leave(KErrNotReady);
       
  1889         }
       
  1890 
       
  1891     decryptor = CAESDecryptor::NewLC(iCek);
       
  1892     decryptor->Transform(block);
       
  1893     CleanupStack::PopAndDestroy( decryptor );
       
  1894 
       
  1895     for (i = 0; i < KDCFKeySize; i++)
       
  1896         {
       
  1897         block[i] ^= iv[i];
       
  1898         }
       
  1899 
       
  1900     if ( block[ KDCFKeySize - 1 ] > 0 && block[ KDCFKeySize - 1 ] <= 16 )
       
  1901         {
       
  1902         for ( i = KDCFKeySize - block[ KDCFKeySize - 1 ];
       
  1903               i < KDCFKeySize - 1;
       
  1904               ++i )
       
  1905             {
       
  1906             if ( block[ i ] != block[ KDCFKeySize - 1 ] )
       
  1907                 {
       
  1908                 User::Leave( KErrCorrupt );
       
  1909                 }
       
  1910             }
       
  1911 
       
  1912         aMessage.Complete( block[ KDCFKeySize - 1 ] );
       
  1913         DRMLOG2( _L( "CDRMDbSession::CalculatePaddingL: Padding = %d" ),
       
  1914                  block[ KDCFKeySize - 1 ] );
       
  1915 
       
  1916         return;
       
  1917         }
       
  1918 
       
  1919     User::Leave( KErrCorrupt );
       
  1920 
       
  1921 __UHEAP_MARKEND;
       
  1922     }
       
  1923 
       
  1924 // -----------------------------------------------------------------------------
       
  1925 // CDRMDbSession::SecureTimeL
       
  1926 // returns the secure time
       
  1927 // -----------------------------------------------------------------------------
       
  1928 //
       
  1929 void CDRMDbSession::SecureTimeL( const RMessage2& aMessage )
       
  1930     {
       
  1931     DRMLOG( _L( "CDRMDbSession::SecureTimeL" ) );
       
  1932     __UHEAP_MARK;
       
  1933     TPckgBuf< TInt64 > time;
       
  1934     TPckg< TBool > levelPckg( iSecureTime );
       
  1935 
       
  1936     UpdateSecureTime();
       
  1937 
       
  1938     time() = iTrustedTime.Int64();
       
  1939 
       
  1940     IPCWRITE0L( time );
       
  1941     IPCWRITE1L( levelPckg );
       
  1942 
       
  1943     aMessage.Complete( KErrNone );
       
  1944     __UHEAP_MARKEND;
       
  1945     DRMLOG( _L( "CDRMDbSession::SecureTime: ok" ) );
       
  1946     }
       
  1947 
       
  1948 // -----------------------------------------------------------------------------
       
  1949 // CDRMDbSession::EncryptL
       
  1950 //
       
  1951 // -----------------------------------------------------------------------------
       
  1952 //
       
  1953 void CDRMDbSession::EncryptL(const RMessage2& aMessage)
       
  1954     {
       
  1955     TBuf8<KDCFKeySize> iv;
       
  1956     HBufC8* data = NULL;
       
  1957     TPtr8 ptr(NULL, 0, 0);
       
  1958     TBool addPadding;
       
  1959     __UHEAP_MARK;
       
  1960 
       
  1961     DRMLOG(_L("CDRMDbSession::EncryptL"));
       
  1962 
       
  1963     if( iCek.Length() != KDRMKeyLength )
       
  1964         {
       
  1965         User::Leave( KErrNotReady );
       
  1966         }
       
  1967 
       
  1968     SanitizeL( aMessage.GetDesLength(0) );
       
  1969 
       
  1970     addPadding = aMessage.Int2() != 0 ? ETrue : EFalse;
       
  1971     aMessage.Read(0, iv);
       
  1972     data = HBufC8::NewLC(aMessage.GetDesMaxLength(1));
       
  1973     ptr.Set(data->Des());
       
  1974     aMessage.Read(1, ptr);
       
  1975 
       
  1976     AesEncryptL( iCek, iv, addPadding, ptr );
       
  1977 
       
  1978     aMessage.Write(1, ptr);
       
  1979     aMessage.Complete(KErrNone);
       
  1980     CleanupStack::PopAndDestroy( data );
       
  1981     __UHEAP_MARKEND;
       
  1982     DRMLOG(_L("CDRMDbSession::EncryptL: Ok"));
       
  1983     }
       
  1984 
       
  1985 // -----------------------------------------------------------------------------
       
  1986 // CDRMDbSession::DecryptL
       
  1987 // Decrypt data and return it to the caller, using the CEK for this session
       
  1988 // -----------------------------------------------------------------------------
       
  1989 //
       
  1990 void CDRMDbSession::DecryptL(const RMessage2& aMessage)
       
  1991     {
       
  1992     DRMLOG(_L("CDRMDbSession::DecryptL"));
       
  1993 
       
  1994     // If credentials haven't been checked, do it now, check for expired rights
       
  1995     if (iCredentialsChecked == ECheckedAndDenied ||
       
  1996         iCredentialsChecked == ENotChecked &&
       
  1997         VerifyCredentials(iContentId, NULL, EUnknown) != KErrNone)
       
  1998         {
       
  1999         DRMLOG(_L("Decrypt failed: untrusted client"));
       
  2000         aMessage.Complete(KErrAccessDenied);
       
  2001         }
       
  2002     else if ( iConsume && iConsume->IsExpired() )
       
  2003         {
       
  2004         DRMLOG(_L("Decrypt failed: rights expired"));
       
  2005         aMessage.Complete(KErrCANoPermission);
       
  2006         }
       
  2007     else
       
  2008         {
       
  2009         if (iCek.Length() > 0)
       
  2010             {
       
  2011             TBuf8<KDCFKeySize> iv;
       
  2012             HBufC8* data = NULL;
       
  2013             TPtr8 ptr(NULL, 0, 0);
       
  2014             TBool removePadding;
       
  2015 
       
  2016             removePadding = aMessage.Int2() != 0 ? ETrue : EFalse;
       
  2017             aMessage.Read(0, iv);
       
  2018 
       
  2019             data = HBufC8::NewMaxLC(aMessage.GetDesMaxLength(1));
       
  2020 
       
  2021             ptr.Set(data->Des());
       
  2022             aMessage.Read(1, ptr);
       
  2023 
       
  2024             AesDecryptL( iCek,
       
  2025                          iv,
       
  2026                          removePadding,
       
  2027                          ptr );
       
  2028 
       
  2029             aMessage.Write(1, ptr);
       
  2030             aMessage.Complete(KErrNone);
       
  2031             CleanupStack::PopAndDestroy( data );
       
  2032             }
       
  2033         else
       
  2034             {
       
  2035             aMessage.Complete(KErrCANoRights);
       
  2036             }
       
  2037         }
       
  2038     DRMLOG(_L("CDRMDbSession::DecryptL: Ok"));
       
  2039     }
       
  2040 
       
  2041 // -----------------------------------------------------------------------------
       
  2042 // CDRMDbSession::InitializeKeyL
       
  2043 // Initialize the CEK for this session based on the content ID. Also sets the
       
  2044 // content ID for later usage.
       
  2045 // -----------------------------------------------------------------------------
       
  2046 //
       
  2047 void CDRMDbSession::InitializeKeyL( const RMessage2& aMessage )
       
  2048     {
       
  2049     TPtr8 tmp(NULL, 0, 0);
       
  2050     HBufC8* key = NULL;
       
  2051     TInt error = KErrNone;
       
  2052 
       
  2053     DRMLOG( _L( "CDRMDbSession::InitializeKeyL"));
       
  2054     if ( iContentId )
       
  2055         {
       
  2056         delete iContentId;
       
  2057         iContentId = NULL;
       
  2058         }
       
  2059     iContentId  = HBufC8::NewL( User::LeaveIfError( IPCGETDESLEN0 ) );
       
  2060     tmp.Set( iContentId->Des() );
       
  2061     IPCREAD0L( tmp );
       
  2062 
       
  2063     __UHEAP_MARK;
       
  2064     TRAP( error, key = DRMDB.GetDecryptionKeyL( *iContentId  ) );
       
  2065     if ( ( error == KErrCANoRights || error == KErrCANoPermission ) &&
       
  2066         PendingRights( *iContentId , EFalse ) )
       
  2067         {
       
  2068         error = KErrCAPendingRights;
       
  2069         }
       
  2070 
       
  2071     if ( error == KErrNone )
       
  2072         {
       
  2073         iCek.Copy( *key );
       
  2074         delete key;
       
  2075         aMessage.Complete( KErrNone );
       
  2076         }
       
  2077     else
       
  2078         {
       
  2079         aMessage.Complete( error );
       
  2080         }
       
  2081     __UHEAP_MARKEND;
       
  2082     DRMLOG2( _L( "CDRMDbSession::InitializeKeyL: %d" ), error );
       
  2083     }
       
  2084 
       
  2085 // -----------------------------------------------------------------------------
       
  2086 // CDRMDbSession::InitializeGroupKeyL
       
  2087 // Initialize the CEK for this session from a given group key
       
  2088 // -----------------------------------------------------------------------------
       
  2089 //
       
  2090 void CDRMDbSession::InitializeGroupKeyL(const RMessage2& aMessage )
       
  2091     {
       
  2092     HBufC8* groupId = NULL;
       
  2093     HBufC8* groupKey = NULL;
       
  2094     TPtr8 tmp(NULL, 0, 0 );
       
  2095     HBufC8* key = NULL;
       
  2096     TRequestStatus status;
       
  2097     CAESDecryptor* aes = NULL;
       
  2098     CModeCBCDecryptor* cbc = NULL;
       
  2099 
       
  2100     __UHEAP_MARK;
       
  2101 
       
  2102     SanitizeL( aMessage.GetDesLength(0) );
       
  2103     SanitizeL( aMessage.GetDesLength(1) );
       
  2104 
       
  2105     DRMLOG(_L("CDRMDbSession::InitializeGroupKeyL"));
       
  2106     if (aMessage.Int2() == EMethodAES_128_CBC)
       
  2107         {
       
  2108         groupId = HBufC8::NewLC(aMessage.GetDesLength(0));
       
  2109         tmp.Set(groupId->Des());
       
  2110         aMessage.Read(0, tmp);
       
  2111 
       
  2112         groupKey = HBufC8::NewLC(aMessage.GetDesLength(1));
       
  2113         tmp.Set(groupKey->Des());
       
  2114         aMessage.Read(1, tmp);
       
  2115 
       
  2116         key = DRMDB.GetDecryptionKeyL(*groupId);
       
  2117         CleanupStack::PushL(key);
       
  2118 
       
  2119         if ( key )
       
  2120             {
       
  2121             aes = CAESDecryptor::NewLC(*key);
       
  2122             cbc = CModeCBCDecryptor::NewL(aes, groupKey->Left(KDCFKeySize));
       
  2123             CleanupStack::Pop( aes );
       
  2124             iCek.Copy(groupKey->Mid(KDCFKeySize, KDCFKeySize));
       
  2125             cbc->Transform(iCek);
       
  2126             delete cbc;
       
  2127             aMessage.Complete(KErrNone);
       
  2128             }
       
  2129         else
       
  2130             {
       
  2131             aMessage.Complete(KErrCANoRights);
       
  2132             }
       
  2133         CleanupStack::PopAndDestroy(3); // key, groupKey, groupId
       
  2134         }
       
  2135     else
       
  2136         {
       
  2137         aMessage.Complete(KErrNotSupported);
       
  2138         }
       
  2139 
       
  2140     __UHEAP_MARKEND;
       
  2141     DRMLOG(_L("CDRMDbSession::InitializeGroupKeyL: Ok"));
       
  2142     }
       
  2143 
       
  2144 // -----------------------------------------------------------------------------
       
  2145 // CDRMDbSession::GetPreparedDataL
       
  2146 // Returns data which has been allocated before
       
  2147 // -----------------------------------------------------------------------------
       
  2148 //
       
  2149 void CDRMDbSession::GetPreparedDataL( const RMessage2& aMessage )
       
  2150     {
       
  2151     DRMLOG( _L( "CDRMDbSession::GetPreparedDataL" ) );
       
  2152 
       
  2153     if( !iPreparedData )
       
  2154         {
       
  2155         User::Leave( KErrNotReady );
       
  2156         }
       
  2157 
       
  2158     if( iPreparedData->Length() > aMessage.GetDesMaxLength(0) )
       
  2159         {
       
  2160         User::Leave(KErrArgument);
       
  2161         }
       
  2162 
       
  2163     IPCWRITE0L( iPreparedData->Des() );
       
  2164 
       
  2165     aMessage.Complete( KErrNone );
       
  2166     DRMLOG( _L( "CDRMDbSession::GetPreparedDataL: ok" ) );
       
  2167 
       
  2168     // Delete the data
       
  2169     delete iPreparedData;
       
  2170     iPreparedData = NULL;
       
  2171     }
       
  2172 
       
  2173 // -----------------------------------------------------------------------------
       
  2174 // CDRMDbSession::IsInCacheL
       
  2175 // Checks whether the given entry is in replay cache or not.
       
  2176 // -----------------------------------------------------------------------------
       
  2177 void CDRMDbSession::IsInCacheL( const RMessage2& aMessage )
       
  2178     {
       
  2179     DRMLOG( _L( "CDRMDbSession::IsInCacheL" ) );
       
  2180 
       
  2181     HBufC8* buf = HBufC8::NewLC(
       
  2182         User::LeaveIfError( IPCGETDESLEN0 ) );
       
  2183 
       
  2184     TPckgBuf< TBool > res;
       
  2185     TPtr8 data( buf->Des() );
       
  2186 
       
  2187     IPCREAD0L( data );
       
  2188 
       
  2189     if ( aMessage.Ptr1() )
       
  2190         {
       
  2191         TPckgBuf< TTime > time;
       
  2192 
       
  2193         IPCREAD1L( time );
       
  2194 
       
  2195         res = REPLAYCACHE.InCacheL( *buf, time() );
       
  2196         }
       
  2197     else
       
  2198         {
       
  2199         res = REPLAYCACHE.InCacheL( *buf );
       
  2200         }
       
  2201 
       
  2202     CleanupStack::PopAndDestroy( buf );
       
  2203 
       
  2204     IPCWRITE2L( res );
       
  2205 
       
  2206     aMessage.Complete( KErrNone );
       
  2207 
       
  2208     DRMLOG( _L( "CDRMDbSession::IsInCache ok" ) );
       
  2209     }
       
  2210 
       
  2211 // -----------------------------------------------------------------------------
       
  2212 // CDRMDbSession::AddToCacheL
       
  2213 // Adds an entry to replay cache.
       
  2214 // -----------------------------------------------------------------------------
       
  2215 void CDRMDbSession::AddToCacheL( const RMessage2& aMessage )
       
  2216     {
       
  2217     DRMLOG( _L( "CDRMDbSession::AddToCacheL" ) );
       
  2218 
       
  2219     HBufC8* buf = NULL;
       
  2220 
       
  2221     UpdateSecureTime();
       
  2222 
       
  2223     if ( !iSecureTime )
       
  2224         {
       
  2225         // DoSomething!
       
  2226         }
       
  2227 
       
  2228     buf = HBufC8::NewLC(
       
  2229         User::LeaveIfError( IPCGETDESLEN0 ) );
       
  2230 
       
  2231     TPtr8 data( buf->Des() );
       
  2232 
       
  2233     IPCREAD0L( data );
       
  2234 
       
  2235     if ( aMessage.Ptr1() )
       
  2236         {
       
  2237         TPckgBuf< TTime > time;
       
  2238 
       
  2239         IPCREAD1L( time );
       
  2240 
       
  2241         REPLAYCACHE.AddL( *buf, time(), iTrustedTime );
       
  2242         }
       
  2243 
       
  2244     else
       
  2245         {
       
  2246         REPLAYCACHE.AddL( *buf, iTrustedTime );
       
  2247         }
       
  2248 
       
  2249     CleanupStack::PopAndDestroy( buf );
       
  2250 
       
  2251     aMessage.Complete( KErrNone );
       
  2252 
       
  2253     DRMLOG( _L( "CDRMDbSession::AddToCacheL ok" ) );
       
  2254     }
       
  2255 
       
  2256 // -----------------------------------------------------------------------------
       
  2257 // CDRMDbSession::AddDomainROL
       
  2258 // Add domain ro xml data
       
  2259 // -----------------------------------------------------------------------------
       
  2260 //
       
  2261 void CDRMDbSession::AddDomainROL( const RMessage2& aMessage )
       
  2262     {
       
  2263     DRMLOG( _L( "CDRMDbSession::AddDomainROL" ) );
       
  2264     __UHEAP_MARK;
       
  2265     HBufC8* RoId = NULL;
       
  2266     HBufC8* XMLData = NULL;
       
  2267     TInt size = 0;
       
  2268     TPtr8 data( NULL, 0 );
       
  2269 
       
  2270     size = User::LeaveIfError( IPCGETDESLEN0 );
       
  2271     RoId = HBufC8::NewLC( size );
       
  2272 
       
  2273     size = User::LeaveIfError( IPCGETDESLEN1 );
       
  2274     XMLData = HBufC8::NewLC( size );
       
  2275 
       
  2276     data.Set( RoId->Des() );
       
  2277     IPCREAD0L( data );
       
  2278 
       
  2279     data.Set( XMLData->Des() );
       
  2280     IPCREAD1L( data );
       
  2281 
       
  2282     DRMDB.AddDomainROL( *RoId, *XMLData );
       
  2283 
       
  2284     CleanupStack::PopAndDestroy( 2 ); // RoId, XMLData
       
  2285 
       
  2286     aMessage.Complete( KErrNone );
       
  2287     __UHEAP_MARKEND;
       
  2288     DRMLOG( _L( "CDRMDbSession::AddDomainROL done" ) );
       
  2289     };
       
  2290 
       
  2291 // -----------------------------------------------------------------------------
       
  2292 // CDRMDbSession::GetDomainROL
       
  2293 // Get domain ro xml data
       
  2294 // -----------------------------------------------------------------------------
       
  2295 //
       
  2296 void CDRMDbSession::GetDomainROL( const RMessage2& aMessage )
       
  2297     {
       
  2298     DRMLOG( _L( "CDRMDbSession::GetDomainROL" ) );
       
  2299 
       
  2300     TInt size = 0;
       
  2301     TPckg< TInt > package( size );
       
  2302     HBufC8* RoId = NULL;
       
  2303     TPtr8 data(NULL, 0);
       
  2304 
       
  2305     // Cleanup.
       
  2306     if ( iPreparedData )
       
  2307         {
       
  2308         delete iPreparedData;
       
  2309         iPreparedData = NULL;
       
  2310         }
       
  2311 
       
  2312     size = User::LeaveIfError( IPCGETDESLEN1 );
       
  2313 
       
  2314     RoId = HBufC8::NewLC( size );
       
  2315 
       
  2316     data.Set( RoId->Des() );
       
  2317     IPCREAD1L( data );
       
  2318 
       
  2319     iPreparedData = DRMDB.GetDomainROL( *RoId );
       
  2320 
       
  2321     size = iPreparedData->Length();
       
  2322 
       
  2323     IPCWRITE0L( package );
       
  2324 
       
  2325     CleanupStack::PopAndDestroy( RoId );
       
  2326 
       
  2327     aMessage.Complete( KErrNone );
       
  2328 
       
  2329     DRMLOG( _L( "CDRMDbSession::GetDomainROL ok" ) );
       
  2330     };
       
  2331 
       
  2332 // -----------------------------------------------------------------------------
       
  2333 // CDRMDbSession::DeleteDomainROL
       
  2334 // Delete domain ro xml data
       
  2335 // -----------------------------------------------------------------------------
       
  2336 //
       
  2337 void CDRMDbSession::DeleteDomainROL( const RMessage2& aMessage )
       
  2338     {
       
  2339     DRMLOG( _L( "CDRMDbSession::DeleteDomainROL" ) );
       
  2340     __UHEAP_MARK;
       
  2341     TPtr8 data( NULL, 0 );
       
  2342     TInt size = 0;
       
  2343 
       
  2344     size = User::LeaveIfError( IPCGETDESLEN0 );
       
  2345 
       
  2346 
       
  2347     HBufC8* RoId = HBufC8::NewLC( size );
       
  2348 
       
  2349     data.Set( RoId->Des() );
       
  2350 
       
  2351     IPCREAD0L( data );
       
  2352 
       
  2353     DRMDB.DeleteDomainROL( *RoId );
       
  2354 
       
  2355     CleanupStack::PopAndDestroy( RoId );
       
  2356 
       
  2357     aMessage.Complete( KErrNone );
       
  2358     __UHEAP_MARKEND;
       
  2359     DRMLOG( _L( "CDRMDbSession::DeleteDomainROL ok" ) );
       
  2360     };
       
  2361 
       
  2362 
       
  2363 // -----------------------------------------------------------------------------
       
  2364 // CDRMDbSession::GetDomainRosForCidL
       
  2365 // Return the domain ROs for a content ID in a buffer. Each RO is preceded
       
  2366 // by a length field
       
  2367 // -----------------------------------------------------------------------------
       
  2368 //
       
  2369 void CDRMDbSession::GetDomainRosForCidL(
       
  2370     const RMessage2& aMessage)
       
  2371     {
       
  2372     DRMLOG(_L("CDRMDbSession::GetDomainRosForCidL"));
       
  2373     TInt size(0);
       
  2374     TInt roSize(0);
       
  2375     TInt pos = 0;
       
  2376     TInt indexLatest = -1;
       
  2377     TTime timeStamp = 0;
       
  2378     TTime timeLatest = 0;
       
  2379     TPckg<TInt> pkg(size);
       
  2380     TPtr8 ptr(NULL, 0);
       
  2381     TPtrC8 elementPtr(KNullDesC8);
       
  2382     TPckg<TInt> roSizePkg(roSize);
       
  2383     HBufC8* element = NULL;
       
  2384     HBufC8* id(NULL);
       
  2385     HBufC8* ro(NULL);
       
  2386     CDRMPointerArray<CDRMPermission>*
       
  2387         rights( CDRMPointerArray<CDRMPermission>::NewLC() );
       
  2388     rights->SetAutoCleanup(ETrue);
       
  2389 
       
  2390     delete iPreparedData;
       
  2391     iPreparedData = NULL;
       
  2392 
       
  2393     SanitizeL( aMessage.GetDesLength(0) );
       
  2394 
       
  2395     id = HBufC8::NewLC(aMessage.GetDesLength(0));
       
  2396     ptr.Set(id->Des());
       
  2397     aMessage.Read(0, ptr);
       
  2398 
       
  2399     TRAPD(r, DRMDB.GetDBEntryByContentIDL(*id, *rights));
       
  2400 
       
  2401     if (r == KErrCANoRights || r == KErrCANoPermission )
       
  2402         {
       
  2403         r = KErrNone;
       
  2404         }
       
  2405     User::LeaveIfError(r);
       
  2406 
       
  2407     for (TInt i(0); i < rights->Count(); i++)
       
  2408         {
       
  2409         if ( (*rights)[i]->iDomainID )
       
  2410             {
       
  2411             ro = DRMDB.GetDomainROL(*(*rights)[i]->iRoID);
       
  2412             CleanupStack::PushL(ro);
       
  2413 
       
  2414             elementPtr.Set(ExtractElement(*ro, KTimeStamp, pos));
       
  2415 
       
  2416             /* Check whether the timestamp was found or not and whether it is
       
  2417                the newest one so far or not */
       
  2418             if (pos >= 0)
       
  2419                 {
       
  2420                 element = elementPtr.AllocLC();
       
  2421                 timeStamp = Iso8601ToTime(*element);
       
  2422                 CleanupStack::PopAndDestroy(element);
       
  2423 
       
  2424                 if (timeStamp > timeLatest)
       
  2425                     {
       
  2426                     indexLatest = i;
       
  2427                     }
       
  2428                 }
       
  2429             CleanupStack::PopAndDestroy(ro);
       
  2430             ro = NULL;
       
  2431             }
       
  2432         pos = 0;
       
  2433         }
       
  2434 
       
  2435     /* At least one timestamp was found */
       
  2436     if (indexLatest >= 0 && indexLatest < rights->Count())
       
  2437         {
       
  2438         ro = DRMDB.GetDomainROL(*(*rights)[indexLatest]->iRoID);
       
  2439         CleanupStack::PushL(ro);
       
  2440 
       
  2441         roSize = ro->Size();
       
  2442         if ( !iPreparedData )
       
  2443             {
       
  2444             iPreparedData = HBufC8::NewL(sizeof (TInt) + roSize);
       
  2445             }
       
  2446         else
       
  2447             {
       
  2448             iPreparedData = iPreparedData->ReAllocL(
       
  2449                 size + sizeof (TInt) + roSize );
       
  2450             }
       
  2451         ptr.Set(iPreparedData->Des());
       
  2452         ptr.Append(roSizePkg);
       
  2453         ptr.Append(*ro);
       
  2454         size += sizeof (TInt) + roSize;
       
  2455         CleanupStack::PopAndDestroy(ro);
       
  2456         }
       
  2457 
       
  2458     aMessage.Write(1, pkg);
       
  2459     CleanupStack::PopAndDestroy( id );
       
  2460     CleanupStack::PopAndDestroy( rights );
       
  2461 
       
  2462     aMessage.Complete(KErrNone);
       
  2463     DRMLOG(_L("CDRMDbSession::GetDomainRosForCidL ok"));
       
  2464     }
       
  2465 
       
  2466 
       
  2467 //------------------------------------------------------------------------------
       
  2468 // CDRMDbSession::DeleteExpiredPermissionsL
       
  2469 // Delete expired permissions if we have secure time.
       
  2470 //------------------------------------------------------------------------------
       
  2471 void CDRMDbSession::DeleteExpiredPermissionsL( const RMessage2& aMessage )
       
  2472     {
       
  2473     DRMLOG( _L( "CDRMDbSession::DeleteExpiredPermissionsL" ) );
       
  2474     CDRMActiveOperation* active( NULL );
       
  2475     TTime time;
       
  2476 
       
  2477     User::LeaveIfError( VerifyCredentials(NULL, NULL, EUnknown) );
       
  2478     if( iCredentialsChecked == ECheckedAndDenied )
       
  2479         {
       
  2480         User::Leave( KErrPermissionDenied );
       
  2481         }
       
  2482 
       
  2483     UpdateSecureTime();
       
  2484 
       
  2485     if ( iSecureTime )
       
  2486         {
       
  2487         time = iTrustedTime;
       
  2488         }
       
  2489     else
       
  2490         {
       
  2491         time = Time::NullTTime();
       
  2492         }
       
  2493 
       
  2494     if ( iPendingRequest )
       
  2495         {
       
  2496         User::Leave( KErrAlreadyExists );
       
  2497         }
       
  2498 
       
  2499     active = CDRMActiveOperation::NewLC( aMessage, *this,
       
  2500                                          CDRMActiveOperation::EOperationDeleteExpired );
       
  2501     active->ActivateL( DRMDB, iTrustedTime );
       
  2502 
       
  2503     iPendingRequest = active;
       
  2504 
       
  2505     CleanupStack::Pop( active );
       
  2506 
       
  2507     DRMLOG( _L( "CDRMDbSession::DeleteExpiredPermissionsL ok" ) );
       
  2508     }
       
  2509 
       
  2510 // -----------------------------------------------------------------------------
       
  2511 // CDRMDbSession::SetEstimatedArrivalL
       
  2512 // set the estimated arrival time for the content uri
       
  2513 // -----------------------------------------------------------------------------
       
  2514 //
       
  2515 void CDRMDbSession::SetEstimatedArrivalL( const RMessage2& aMessage )
       
  2516     {
       
  2517     HBufC8* CID = NULL;
       
  2518     TFileName fileName;
       
  2519     TInt length = 0;
       
  2520     TPtr8 inRead( NULL, 0 );
       
  2521     TTimeIntervalSeconds interval = 0;
       
  2522     TPckg<TTimeIntervalSeconds> package( interval );
       
  2523     RPointerArray<CDRMXOma>& array = XOMAHEADER;
       
  2524     CDRMXOma* omaData = NULL;
       
  2525 
       
  2526     // Read the content id
       
  2527     length = User::LeaveIfError( IPCGETDESLEN0 );
       
  2528     CID = HBufC8::NewLC( length );
       
  2529     inRead.Set( CID->Des() );
       
  2530     IPCREAD0L( inRead );
       
  2531 
       
  2532     // Read the interval
       
  2533     IPCREAD1L( package );
       
  2534 
       
  2535 
       
  2536     for( TInt i = 0; i < array.Count(); i++ )
       
  2537         {
       
  2538         if( !CID->Compare( (array)[i]->ContentID() ) )
       
  2539             {
       
  2540             omaData = (array)[i];
       
  2541             break;
       
  2542             }
       
  2543         }
       
  2544 
       
  2545     // Update the secure time
       
  2546     UpdateSecureTime();
       
  2547 
       
  2548     if( omaData ) // Exists, update
       
  2549         {
       
  2550         omaData->SetWaitTimeL( interval );
       
  2551         omaData->SetTimeStampL( iTrustedTime );
       
  2552         }
       
  2553     else // Doesn't exist, create a new one
       
  2554         {
       
  2555         omaData = CDRMXOma::NewLC( *CID, iTrustedTime, interval );
       
  2556         array.AppendL( omaData );
       
  2557         CleanupStack::Pop( omaData );
       
  2558         }
       
  2559 
       
  2560     CleanupStack::PopAndDestroy( CID );
       
  2561 
       
  2562     // Complete the command
       
  2563     aMessage.Complete( KErrNone );
       
  2564     };
       
  2565 
       
  2566 // -----------------------------------------------------------------------------
       
  2567 // CDRMDbSession::GetEstimatedArrivalL
       
  2568 // get the estimated arrival time for the content uri
       
  2569 // -----------------------------------------------------------------------------
       
  2570 //
       
  2571 void CDRMDbSession::GetEstimatedArrivalL( const RMessage2& aMessage )
       
  2572     {
       
  2573     HBufC8* CID = NULL;
       
  2574     TInt length = 0;
       
  2575     TPtr8 inRead( NULL, 0 );
       
  2576     RPointerArray<CDRMXOma>& array = XOMAHEADER;
       
  2577     CDRMXOma* omaData = NULL;
       
  2578     TInt64 interval = 0;
       
  2579     TInt i = 0;
       
  2580     TTimeIntervalSeconds result = 0;
       
  2581 
       
  2582     // Read the content id
       
  2583     length = User::LeaveIfError( IPCGETDESLEN0 );
       
  2584     CID = HBufC8::NewLC( length );
       
  2585     inRead.Set( CID->Des() );
       
  2586     IPCREAD0L( inRead );
       
  2587 
       
  2588     for( ; i < array.Count(); i++ )
       
  2589         {
       
  2590         if( !CID->Compare( (array)[i]->ContentID() ) )
       
  2591             {
       
  2592             omaData = (array)[i];
       
  2593             break;
       
  2594             }
       
  2595         }
       
  2596 
       
  2597     // Update the secure time
       
  2598     UpdateSecureTime();
       
  2599 
       
  2600     if( omaData ) // Exists, update
       
  2601         {
       
  2602 
       
  2603         // Special case, the rights have expired before, but have not been removed
       
  2604         // so that we do not lose the notification
       
  2605         if( omaData->WaitTime().Int() == KErrCAPendingRights )
       
  2606             {
       
  2607             interval = -1; // Fixed value for this case:
       
  2608                            // -1 means the rights should have arrived already
       
  2609 
       
  2610             delete omaData;
       
  2611             omaData = 0;
       
  2612 
       
  2613             array.Remove( i );
       
  2614             }
       
  2615         else
       
  2616             {
       
  2617             // Update the secure time
       
  2618             UpdateSecureTime();
       
  2619 
       
  2620             interval = omaData->WaitTime().Int();
       
  2621             interval -= ( iTrustedTime.Int64() - omaData->TimeStamp().Int64() ) /
       
  2622                 KMicrosecondsToSecond;
       
  2623 
       
  2624             if( interval <= 0 )
       
  2625                 {
       
  2626                 interval = -1; // Fixed value for this case:
       
  2627                                // -1 means the rights should have arrived already
       
  2628 
       
  2629                 // Clean up the data: if the function fails before this
       
  2630                 // the instance remains like it should
       
  2631                 delete omaData;
       
  2632                 omaData = 0;
       
  2633 
       
  2634                 array.Remove( i ); // Remove from the array
       
  2635                 }
       
  2636             }
       
  2637         result = I64INT(interval);
       
  2638         TPckg<TTimeIntervalSeconds> package( result );
       
  2639         IPCWRITE1L( package );
       
  2640         }
       
  2641     else // Doesn't exist, create a new one
       
  2642         {
       
  2643         User::Leave( KErrNotFound );
       
  2644         }
       
  2645 
       
  2646     CleanupStack::PopAndDestroy( CID );
       
  2647 
       
  2648     // Complete the command
       
  2649     aMessage.Complete( KErrNone );
       
  2650     };
       
  2651 
       
  2652 
       
  2653 
       
  2654 //------------------------------------------------------------------------------
       
  2655 // CDRMDbSession::PendingRights
       
  2656 // Check if rights are pending
       
  2657 //------------------------------------------------------------------------------
       
  2658 TBool CDRMDbSession::PendingRights(const TDesC8& aCid, TBool aRemoval)
       
  2659     {
       
  2660     TBool f = EFalse;
       
  2661     RPointerArray<CDRMXOma>& array = XOMAHEADER;
       
  2662     CDRMXOma* omaData = NULL;
       
  2663     TInt64 interval = 0;
       
  2664     TInt i = 0;
       
  2665     TTimeIntervalSeconds result = 0;
       
  2666 
       
  2667     for( ; i < array.Count() && !f; i++ )
       
  2668         {
       
  2669         if( !aCid.Compare( (array)[i]->ContentID() ) )
       
  2670             {
       
  2671             omaData = (array)[i];
       
  2672             // Exists and is different from KErrCAPendingRights -> update
       
  2673             if( omaData && omaData->WaitTime().Int() != KErrCAPendingRights )
       
  2674                 {
       
  2675                 // Update the secure time
       
  2676                 UpdateSecureTime();
       
  2677                 interval = omaData->WaitTime().Int();
       
  2678                 interval -= ( iTrustedTime.Int64() - omaData->TimeStamp().Int64() ) /
       
  2679                     KMicrosecondsToSecond;
       
  2680 
       
  2681                 // check if removal from the list is needed
       
  2682                 if( aRemoval && interval <= 0 )
       
  2683                     {
       
  2684                     TRAPD( error, omaData->SetWaitTimeL( KErrCAPendingRights ) );
       
  2685                     error = error; // remove error
       
  2686                     }
       
  2687                 f = ETrue;
       
  2688                 }
       
  2689             }
       
  2690         }
       
  2691     return f;
       
  2692     }
       
  2693 
       
  2694 
       
  2695 
       
  2696 //------------------------------------------------------------------------------
       
  2697 // CDRMDbSession::GetUdtDataL
       
  2698 // Gets the user data transfer header data
       
  2699 //------------------------------------------------------------------------------
       
  2700 void CDRMDbSession::GetUdtDataL( const RMessage2& aMessage )
       
  2701     {
       
  2702     DRMLOG( _L( "CDRMDbSession::GetUdtDataL" ) );
       
  2703     __UHEAP_MARK;
       
  2704     // Usage intent.
       
  2705     HBufC8* udtData = NULL;
       
  2706 
       
  2707     // Get the key
       
  2708     udtData = DRMDB.GetUdtDataLC();
       
  2709 
       
  2710     // Write the udt data to the client.
       
  2711     // This shouldn't fail anyway.
       
  2712     IPCWRITE0L( *udtData );
       
  2713 
       
  2714     CleanupStack::PopAndDestroy( udtData );
       
  2715 
       
  2716     aMessage.Complete( KErrNone );
       
  2717     __UHEAP_MARKEND;
       
  2718     DRMLOG( _L( "CDRMDbSession::GetUdtDataL: Ok" ) );
       
  2719     };
       
  2720 
       
  2721 //------------------------------------------------------------------------------
       
  2722 // CDRMDbSession::InitiateUdtL
       
  2723 // Initiate user data transfer
       
  2724 //------------------------------------------------------------------------------
       
  2725 void CDRMDbSession::InitiateUdtL( const RMessage2& aMessage )
       
  2726     {
       
  2727     DRMLOG( _L( "CDRMDbSession::InitiateUdtL" ) );
       
  2728     __UHEAP_MARK;
       
  2729 
       
  2730     HBufC8* encryptionKey = NULL;
       
  2731     TInt size = 0;
       
  2732     TPtr8 data( NULL, 0 );
       
  2733 
       
  2734     SanitizeL( aMessage.GetDesLength(0));
       
  2735 
       
  2736     size = User::LeaveIfError( IPCGETDESLEN0 );
       
  2737     encryptionKey = HBufC8::NewLC( size );
       
  2738 
       
  2739     data.Set( encryptionKey->Des() );
       
  2740     IPCREAD0L( data );
       
  2741 
       
  2742     // The encrypted data is encrypted with 2048 byte key, it always needs to be atleast this long
       
  2743     if( encryptionKey->Length() < 254)
       
  2744         {
       
  2745         User::Leave(KErrArgument);
       
  2746         }
       
  2747 
       
  2748     DRMDB.InitiateUdtL( *encryptionKey );
       
  2749 
       
  2750     CleanupStack::PopAndDestroy( encryptionKey );
       
  2751 
       
  2752     aMessage.Complete( KErrNone );
       
  2753     __UHEAP_MARKEND;
       
  2754 
       
  2755     DRMLOG( _L( "CDRMDbSession::InitiateUdtL done" ) );
       
  2756     };
       
  2757 
       
  2758 //------------------------------------------------------------------------------
       
  2759 // CDRMDbSession::InitExportOrhanedCIDsL
       
  2760 // Create and export the list of orphaned content id's
       
  2761 //------------------------------------------------------------------------------
       
  2762 void CDRMDbSession::InitExportOrphanedCIDsL( const RMessage2& aMessage )
       
  2763     {
       
  2764     DRMLOG( _L( "CDRMDbSession::InitExportOrphanedCIDsL" ) );
       
  2765     CDRMActiveOperation* active( NULL );
       
  2766     TBool performScan = EFalse;
       
  2767 
       
  2768     User::LeaveIfError( VerifyCredentials(NULL,NULL,ContentAccess::EUnknown) );
       
  2769 
       
  2770     if ( iPendingRequest )
       
  2771         {
       
  2772         User::Leave( KErrAlreadyExists );
       
  2773         }
       
  2774 
       
  2775     // if the old filename exists, delete it, a new operation starts
       
  2776     if( iFileName )
       
  2777         {
       
  2778         delete iFileName;
       
  2779         iFileName = NULL;
       
  2780         }
       
  2781 
       
  2782     // Read the scan data:
       
  2783     performScan = aMessage.Int0() != 0 ? ETrue : EFalse;
       
  2784 
       
  2785 
       
  2786     active = CDRMActiveOperation::NewLC( aMessage, *this,
       
  2787                                          CDRMActiveOperation::EOperationExportObsolete );
       
  2788 
       
  2789 #ifndef RD_MULTIPLE_DRIVE
       
  2790 
       
  2791     active->ActivateL( DRMDB, RFSSESSION, KDRMDbTempPath, performScan );
       
  2792 
       
  2793 #else //RD_MULTIPLE_DRIVE
       
  2794 
       
  2795     TInt driveNumber( -1 );
       
  2796     TChar driveLetter;
       
  2797     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
       
  2798 
       
  2799     RFSSESSION.DriveToChar( driveNumber, driveLetter );
       
  2800 
       
  2801     TFileName dbTempPath;
       
  2802     dbTempPath.Format( KDbTempPath, (TUint)driveLetter );
       
  2803 
       
  2804     active->ActivateL( DRMDB, RFSSESSION, dbTempPath, performScan );
       
  2805 
       
  2806 #endif
       
  2807 
       
  2808     iPendingRequest = active;
       
  2809 
       
  2810     CleanupStack::Pop( active );
       
  2811 
       
  2812     DRMLOG( _L( "CDRMDbSession::InitExportOrphanedCIDsL: ok" ) );
       
  2813     };
       
  2814 
       
  2815 
       
  2816 //------------------------------------------------------------------------------
       
  2817 // CDRMDbSession::ExportOrhanedCIDsL
       
  2818 // Create and export the list of orphaned content id's
       
  2819 //------------------------------------------------------------------------------
       
  2820 void CDRMDbSession::ExportOrphanedCIDsL( const RMessage2& aMessage )
       
  2821     {
       
  2822     DRMLOG( _L( "CDRMDbSession::ExportOrphanedCIDsL" ) );
       
  2823     if( !iFileName )
       
  2824         {
       
  2825         aMessage.Complete( KErrNotReady );
       
  2826         return;
       
  2827         }
       
  2828 
       
  2829     if( iFileName->Length() > aMessage.GetDesMaxLength(0) )
       
  2830         {
       
  2831         User::Leave(KErrArgument);
       
  2832         }
       
  2833 
       
  2834     // It is virtually impossible to make WriteL to leave in this case,
       
  2835     // but anything is still possible...
       
  2836     IPCWRITE0L( *iFileName );
       
  2837 
       
  2838     // if everything went well, delete the filename if not leave it
       
  2839     delete iFileName;
       
  2840     iFileName = NULL;
       
  2841 
       
  2842     // All done
       
  2843     aMessage.Complete( KErrNone );
       
  2844 
       
  2845     DRMLOG( _L( "CDRMDbSession::ExportOrphanedCIDsL: ok" ) );
       
  2846     };
       
  2847 
       
  2848 // ----------------------------------------------------------------------------
       
  2849 // CDRMDbSession::UnwrapMacAndRekL
       
  2850 // Unwraps public key encrypted MAC and REK keys
       
  2851 // ----------------------------------------------------------------------------
       
  2852 //
       
  2853 void CDRMDbSession::UnwrapMacAndRekL( const RMessage2& aMessage, TBool aDomainRo )
       
  2854     {
       
  2855     DRMLOG( _L( "CDRMDbSession::UnwrapMacAndRekL" ) );
       
  2856 
       
  2857     __UHEAP_MARK;
       
  2858 
       
  2859     MDrmKeyStorage* storage;
       
  2860     TBuf8<OmaCrypto::KMacSize> mac;
       
  2861     TBuf8<OmaCrypto::KKeySize> rek;
       
  2862     HBufC8* data = NULL;
       
  2863     TPtr8 dataPtr(0, 0);
       
  2864     TPtrC8 macAndRekPtr(0, 0);
       
  2865     HBufC8* riId = NULL;
       
  2866     TPtr8 riIdPtr(0, 0);
       
  2867     HBufC8* domainId = NULL;
       
  2868     TPtr8 domainIdPtr(0, 0);
       
  2869     CDRMRIContext* riContext = NULL;
       
  2870     TInt size = 0;
       
  2871     TKeyTransportScheme transport;
       
  2872     HBufC8* unwrappedMacAndRek = NULL;
       
  2873     CDRMDomainContext* domainContext;
       
  2874     HBufC8* domainKey = NULL;
       
  2875 
       
  2876     DRMLOG(_L("CDRMDbSession::UnwrapMacAndRekL"));
       
  2877 
       
  2878 
       
  2879 
       
  2880     SanitizeL( aMessage.GetDesLength(0) );
       
  2881     SanitizeL( aMessage.GetDesLength(1) );
       
  2882 
       
  2883     size = User::LeaveIfError( IPCGETDESLEN0 );
       
  2884     data = HBufC8::NewLC( size );
       
  2885 
       
  2886     size = User::LeaveIfError( IPCGETDESLEN1 );
       
  2887     riId = HBufC8::NewLC( size );
       
  2888 
       
  2889     if(aDomainRo)
       
  2890         {
       
  2891         SanitizeL( aMessage.GetDesLength(2) );
       
  2892         size = User::LeaveIfError( IPCGETDESLEN2 );
       
  2893         domainId = HBufC8::NewLC( size );
       
  2894         }
       
  2895 
       
  2896     dataPtr.Set( data->Des() );
       
  2897     IPCREAD0L( dataPtr );
       
  2898 
       
  2899     riIdPtr.Set( riId->Des() );
       
  2900     IPCREAD1L( riIdPtr );
       
  2901 
       
  2902     if(aDomainRo)
       
  2903         {
       
  2904         domainIdPtr.Set( domainId->Des() );
       
  2905         IPCREAD2L( domainIdPtr );
       
  2906         }
       
  2907 
       
  2908     // The first byte defines the transport scheme
       
  2909     transport = static_cast<TKeyTransportScheme>(dataPtr[0]);
       
  2910     macAndRekPtr.Set(dataPtr.Mid(1));
       
  2911 
       
  2912     DRMLOG2(_L("Transport scheme: %d"), transport);
       
  2913     DRMLOG(_L("MAC + REK:"));
       
  2914     DRMLOGHEX(macAndRekPtr);
       
  2915 
       
  2916     if ( !iRoapClientConnected )
       
  2917         {
       
  2918         User::LeaveIfError( iRoapClient.Connect() );
       
  2919         iRoapClientConnected = ETrue;
       
  2920         }
       
  2921 
       
  2922     if (!aDomainRo)
       
  2923         {
       
  2924         // get the trusted root from the rights issuer context
       
  2925         riContext = iRoapClient.GetRIContextL(riIdPtr);
       
  2926         if ( !riContext )
       
  2927             {
       
  2928             DRMLOG(_L("RI not registered"));
       
  2929             User::Leave(KErrRightsServerRiNotRegistered);
       
  2930             }
       
  2931         CleanupStack::PushL(riContext);
       
  2932         // connect to the storage of our PKI keys
       
  2933         storage = DrmKeyStorageNewL();
       
  2934         TCleanupItem storageCleanup( DeleteObject, storage );
       
  2935         CleanupStack::PushL(storageCleanup);
       
  2936         storage->SelectTrustedRootL(riContext->SelectedDeviceRoot());
       
  2937 
       
  2938         if (transport == EOma)
       
  2939             {
       
  2940             OmaCrypto::RsaKemKwsDecryptL(storage, macAndRekPtr, rek, mac);
       
  2941             }
       
  2942         else
       
  2943             {
       
  2944             CmlaCrypto::CmlaIpDecryptL(transport, storage, macAndRekPtr, rek, mac);
       
  2945             }
       
  2946         CleanupStack::PopAndDestroy(4, data);
       
  2947         }
       
  2948     else
       
  2949         {
       
  2950         domainContext = iRoapClient.GetDomainContextL(domainIdPtr);
       
  2951         if ( !domainContext )
       
  2952             {
       
  2953             DRMLOG(_L("Domain not registered"));
       
  2954             User::Leave(KErrRightsServerDomainNotRegistered);
       
  2955             }
       
  2956         CleanupStack::PushL(domainContext);
       
  2957 
       
  2958         // last three digits presents the domain generation
       
  2959         TInt generation = 0;
       
  2960         TLex8 lex( domainIdPtr.Right(3));
       
  2961         lex.Val(generation);
       
  2962 
       
  2963         domainKey = domainContext->DomainKeyL(generation);
       
  2964         CleanupStack::PushL( domainKey );
       
  2965 
       
  2966         // unwrap MAC and REK first with the domain key, the CEK with REK
       
  2967         unwrappedMacAndRek = OmaCrypto::AesUnwrapL(*domainKey, macAndRekPtr);
       
  2968         CleanupStack::PushL(unwrappedMacAndRek);
       
  2969 
       
  2970         mac.Copy( unwrappedMacAndRek->Left( OmaCrypto::KKeySize) );
       
  2971         rek.Copy( unwrappedMacAndRek->Right( OmaCrypto::KKeySize) );
       
  2972         CleanupStack::PopAndDestroy(6, data);
       
  2973         }
       
  2974 
       
  2975     DRMLOG(_L("REK:"));
       
  2976     DRMLOGHEX(rek);
       
  2977     DRMLOG(_L("MAC:"));
       
  2978     DRMLOGHEX(mac);
       
  2979 
       
  2980     iMac.Copy(mac);
       
  2981     iRek.Copy(rek);
       
  2982 
       
  2983     aMessage.Complete( KErrNone );
       
  2984 
       
  2985     __UHEAP_MARKEND;
       
  2986 
       
  2987     DRMLOG( _L( "CDRMDbSession::UnwrapMacAndRekL: ok" ) );
       
  2988     }
       
  2989 
       
  2990 //------------------------------------------------------------------------------
       
  2991 // CDRMDbSession::FindParentsAndRemoveUnusableL()
       
  2992 // Find the best ROs from aList and store references to aBest.
       
  2993 //------------------------------------------------------------------------------
       
  2994 void CDRMDbSession::FindParentsAndRemoveUnusableL( RDRMPermissionList& aList,
       
  2995                                                    const TDesC8& aURI,
       
  2996                                                    CDRMPointerArray<HBufC8>& aCids,
       
  2997                                                    const TIntent aIntent,
       
  2998                                                    const TTime& aDrmTime,
       
  2999                                                    TUint32& aReason )
       
  3000     {
       
  3001 
       
  3002     CDRMPermissionList *permList = NULL;
       
  3003     TInt error = KErrNone;
       
  3004     HBufC8* uri = NULL;
       
  3005 
       
  3006     aCids.ResetAndDestroy();
       
  3007 
       
  3008 
       
  3009     // to separate parents and children we store the content id, since the content id is needed
       
  3010     // by drm consume:
       
  3011     for( TInt count = 0; count < aList.Count(); count++ )
       
  3012         {
       
  3013         uri = aURI.AllocLC();
       
  3014         aCids.AppendL( uri );
       
  3015         CleanupStack::Pop( uri ); // uri
       
  3016         }
       
  3017 
       
  3018 
       
  3019     // Go though the list and remove the unusable RO's
       
  3020     for( TInt i = aList.Count() - 1 ; i >= 0; i-- )
       
  3021         {
       
  3022         // If the RO has valid parent rights add them to the list
       
  3023         if( aList[i]->iParentUID )
       
  3024             {
       
  3025             permList = CDRMPermissionList::NewLC();
       
  3026             permList->SetAutoCleanup( ETrue );
       
  3027 
       
  3028             TRAP( error, DRMDB.GetDBEntryByContentIDL( *aList[i]->iParentUID, *permList ));
       
  3029             if( !error )
       
  3030                 {
       
  3031                 for( TInt j = 0; j < permList->Count(); j++ )
       
  3032                     {
       
  3033                     // check if the permission is valid and if the RI ID for child and parent
       
  3034                     // match
       
  3035                     if ( aList[i]->iRiId.Compare( (*permList)[j]->iRiId ) == 0 &&
       
  3036                         IsValidPermissionL( *(*permList)[j], aIntent, aDrmTime, aReason ) )
       
  3037                         {
       
  3038                         aList.AppendL( (*permList)[j] );
       
  3039                         (*permList)[j] = 0;
       
  3040                         uri = aList[i]->iParentUID->AllocLC();
       
  3041                         aCids.AppendL( uri );
       
  3042                         CleanupStack::Pop( uri );
       
  3043                         }
       
  3044                     }
       
  3045                 }
       
  3046             CleanupStack::PopAndDestroy( permList );
       
  3047             }
       
  3048 
       
  3049         // If the child is not valid remove it from the list
       
  3050         if ( !IsValidPermissionL( *aList[i], aIntent, aDrmTime, aReason ) )
       
  3051             {
       
  3052             CDRMPermission* perm = aList[i];
       
  3053             delete perm;
       
  3054             aList.Remove( i );
       
  3055 
       
  3056             uri = aCids[i];
       
  3057             delete uri;
       
  3058             aCids.Remove( i );
       
  3059             perm = NULL;
       
  3060             uri = NULL;
       
  3061             }
       
  3062         }
       
  3063     // Now the list should contain only valid RO's or parents of the RO's
       
  3064     // which are valid
       
  3065     }
       
  3066 
       
  3067 
       
  3068 //------------------------------------------------------------------------------
       
  3069 // CDRMDbSession::FindBestROsL
       
  3070 // Find the best ROs from aList and store references to aBest.
       
  3071 //------------------------------------------------------------------------------
       
  3072 TInt CDRMDbSession::FindBestROsL(
       
  3073     RDRMPermissionList& aList,
       
  3074     const TDesC8& aURI,
       
  3075     const TIntent aIntent,
       
  3076     HBufC8*& aUsedURI,
       
  3077     TUint32& aReason )
       
  3078     {
       
  3079     TTime time = Time::NullTTime();
       
  3080     CDRMPointerArray<HBufC8>* uriList = CDRMPointerArray<HBufC8>::NewLC();
       
  3081     uriList->SetAutoCleanup(ETrue);
       
  3082 
       
  3083     TInt bestRo = -1;
       
  3084 
       
  3085     if ( iSecureTime )
       
  3086         {
       
  3087         time = iTrustedTime;
       
  3088         }
       
  3089     else
       
  3090         {
       
  3091         time = Time::NullTTime();
       
  3092         }
       
  3093 
       
  3094     FindParentsAndRemoveUnusableL( aList, aURI, *uriList, aIntent, time, aReason );
       
  3095 
       
  3096     if( aList.Count() == 0 )
       
  3097         {
       
  3098         User::Leave(KErrCANoPermission);
       
  3099         }
       
  3100 
       
  3101     bestRo = GetBestROL( aList, aIntent, aReason );
       
  3102 
       
  3103     // Delete if it already exists
       
  3104     if( aUsedURI )
       
  3105         {
       
  3106         delete aUsedURI;
       
  3107         }
       
  3108     aUsedURI = NULL;
       
  3109 
       
  3110     // if it's not the same as the normal URI return a value otherwise NULL
       
  3111     if( (*uriList)[ bestRo ]->Compare( aURI ) )
       
  3112         {
       
  3113         aUsedURI = (*uriList)[ bestRo ]->AllocL();
       
  3114         }
       
  3115 
       
  3116     CleanupStack::PopAndDestroy( uriList );
       
  3117     return bestRo;
       
  3118     }
       
  3119 
       
  3120 // -----------------------------------------------------------------------------
       
  3121 // CDRMDbSession::IsValidPermissionL
       
  3122 // ETrue if not expired. If the candidate has expired permission (intent,
       
  3123 // not top level), ETrue is returned if the child knows it is a child.
       
  3124 // -----------------------------------------------------------------------------
       
  3125 TBool CDRMDbSession::IsValidPermissionL(
       
  3126     CDRMPermission& aPermission,
       
  3127     const ContentAccess::TIntent aIntent,
       
  3128     const TTime& aTime,
       
  3129     TUint32& aReason )
       
  3130     {
       
  3131     CDRMConstraint* toplevel = NULL;
       
  3132     CDRMConstraint* constraint = NULL;
       
  3133     CDRMDomainContext* domainContext = NULL;
       
  3134     TBool r = ETrue;
       
  3135     #ifdef RD_DRM_METERING
       
  3136     CDRMRIContext* riContext = NULL;
       
  3137     #endif
       
  3138 
       
  3139     toplevel = aPermission.TopLevelConstraint();
       
  3140     if ( toplevel && ( !( toplevel->Valid( aTime, IMSI, aReason ) ) ) )
       
  3141         {
       
  3142         r = EFalse;
       
  3143         }
       
  3144     else
       
  3145         {
       
  3146         constraint = aPermission.ConstraintForIntent( aIntent );
       
  3147         if ( !constraint || constraint &&
       
  3148             ( !( constraint->Valid( aTime, IMSI, aReason ) ) ) )
       
  3149             {
       
  3150             r = EFalse;
       
  3151             }
       
  3152         else if ( aPermission.iDomainID )
       
  3153             {
       
  3154             if ( !iRoapClientConnected )
       
  3155                 {
       
  3156                 User::LeaveIfError( iRoapClient.Connect() );
       
  3157                 iRoapClientConnected = ETrue;
       
  3158                 }
       
  3159             domainContext = iRoapClient.GetDomainContextL( *aPermission.iDomainID );
       
  3160             if ( domainContext )
       
  3161                 {
       
  3162                 delete domainContext;
       
  3163                 }
       
  3164             else
       
  3165                 {
       
  3166                 r = EFalse;
       
  3167                 }
       
  3168 
       
  3169             }
       
  3170 
       
  3171         // If the constraint is software constrained and the sw secureid does not match
       
  3172         // remove it from the list handling
       
  3173         if( r && aPermission.SoftwareConstrained() )
       
  3174             {
       
  3175             _LIT_SECURITY_POLICY_S0(swSidCheck, constraint->iSecureId.iUid);
       
  3176             if (constraint->iActiveConstraints & EConstraintSoftware)
       
  3177                 {
       
  3178                 if (!swSidCheck().CheckPolicy(iClient))
       
  3179                     {
       
  3180                     r = EFalse;
       
  3181                     }
       
  3182                 }
       
  3183             }
       
  3184         }
       
  3185 
       
  3186     #ifdef RD_DRM_METERING
       
  3187 
       
  3188     // Check if metering restricts the content usage
       
  3189     if ( r != EFalse && constraint->iDrmMeteringInfo &&
       
  3190         !constraint->iDrmMeteringInfo->iAllowUseWithoutMetering )
       
  3191         {
       
  3192         if ( !iRoapClientConnected )
       
  3193             {
       
  3194             User::LeaveIfError( iRoapClient.Connect() );
       
  3195             iRoapClientConnected = ETrue;
       
  3196             }
       
  3197         riContext = iRoapClient.GetRIContextL( aPermission.iRiId );
       
  3198         if ( !riContext || !riContext->IsMeteringAllowed() )
       
  3199             {
       
  3200             aReason |= EConstraintMetering;
       
  3201             return EFalse;
       
  3202             }
       
  3203         }
       
  3204 
       
  3205     delete riContext;
       
  3206 
       
  3207     #endif
       
  3208 
       
  3209     return r;
       
  3210     }
       
  3211 
       
  3212 //------------------------------------------------------------------------------
       
  3213 // CDRMDbSession::GetBestROL
       
  3214 // Find the best ROs from aList and store references to aBest.
       
  3215 //------------------------------------------------------------------------------
       
  3216 TInt CDRMDbSession::GetBestROL(
       
  3217     RDRMPermissionList& aList,
       
  3218     const TIntent aIntent,
       
  3219     TUint32& aReason )
       
  3220     {
       
  3221     TInt count( 0 );
       
  3222     TTime time;
       
  3223 
       
  3224     CDRMConstraint* normalized = CDRMConstraint::NewLC();
       
  3225     CDRMConstraint* bestOne = CDRMConstraint::NewLC();
       
  3226 
       
  3227     TInt bestRo( -1 );
       
  3228 
       
  3229     if ( iSecureTime )
       
  3230         {
       
  3231         time = iTrustedTime;
       
  3232         }
       
  3233     else
       
  3234         {
       
  3235         time = Time::NullTTime();
       
  3236         }
       
  3237 
       
  3238     // 'count' is updated if something useful is found, and aList is
       
  3239     // updated if the permission cannot be used.
       
  3240     while  ( count < aList.Count() )
       
  3241         {
       
  3242         CDRMPermission* perm = aList[ count ];
       
  3243         TBool found( EFalse );
       
  3244 
       
  3245         // If there is no constraint for the intent, there is no need to normalize
       
  3246         // There can be no rights to use in that permission
       
  3247         if( perm->ConstraintForIntent( aIntent ) )
       
  3248             {
       
  3249             Normalize( *perm, *normalized, aIntent );
       
  3250             if ( normalized->Valid( time, IMSI, aReason ) )
       
  3251                 {
       
  3252                 found = ETrue;
       
  3253                 }
       
  3254             }
       
  3255 
       
  3256         if ( found )
       
  3257             {
       
  3258             // Compare whether "normalized" is more suitable than "bestOne".
       
  3259             // If this is the first usable child & parent combination,
       
  3260             // take it.
       
  3261             if ( ( bestRo < 0 ) || BetterPermission( *normalized, *bestOne ) )
       
  3262                 {
       
  3263                 // "normalized" is the new "bestOne"
       
  3264                 CDRMConstraint* temp = bestOne;
       
  3265                 bestOne = normalized;
       
  3266                 normalized = temp;
       
  3267 
       
  3268                 bestRo = count;
       
  3269 
       
  3270                 ++count;
       
  3271                 }
       
  3272             else
       
  3273                 {
       
  3274                 // This isn't any better than the previous ones. Throw it away.
       
  3275                 found = EFalse;
       
  3276                 }
       
  3277             }
       
  3278 
       
  3279         if ( !found )
       
  3280             {
       
  3281             // Unusable child.
       
  3282             delete perm; perm = NULL;
       
  3283             aList.Remove( count );
       
  3284             }
       
  3285         }
       
  3286 
       
  3287     CleanupStack::PopAndDestroy( 2 ); // bestOne, normalized
       
  3288 
       
  3289     return bestRo;
       
  3290     }
       
  3291 
       
  3292 // -----------------------------------------------------------------------------
       
  3293 // CDRMDbSession::Normalize
       
  3294 // Normalizes a permission.
       
  3295 // -----------------------------------------------------------------------------
       
  3296 void CDRMDbSession::Normalize( CDRMPermission& aPermission,
       
  3297                                CDRMConstraint& aNormalized,
       
  3298                                const ContentAccess::TIntent aIntent )
       
  3299     {
       
  3300     __ASSERT_DEBUG( aPermission.ConstraintForIntent( aIntent ), User::Invariant() );
       
  3301 
       
  3302     TRAPD( error, aNormalized.DuplicateL( *( aPermission.ConstraintForIntent( aIntent ) ) ) );
       
  3303     if( !error )
       
  3304         {
       
  3305         if ( aPermission.TopLevelConstraint() )
       
  3306             {
       
  3307             aNormalized.Merge( *( aPermission.TopLevelConstraint() ) );
       
  3308             }
       
  3309         }
       
  3310     }
       
  3311 // -----------------------------------------------------------------------------
       
  3312 // CDRMDbSession::BetterPermission
       
  3313 // Compares two permissions, and returns ETrue if aNewOne is more suitable
       
  3314 // for the usage. Assumes both are valid, i.e. not expired.
       
  3315 // -----------------------------------------------------------------------------
       
  3316 TBool CDRMDbSession::BetterPermission( const CDRMConstraint& aNewOne,
       
  3317                                        const CDRMConstraint& aOldOne )
       
  3318     {
       
  3319     // Check Order:
       
  3320     // 1. Full
       
  3321     // 2. Start End, closest end time first
       
  3322     // 3. Interval, shortest first
       
  3323     // 4. Accumulated, shortest first
       
  3324     // 5. Timed Counter, least counters first, longest time first
       
  3325     // 6. Counter, least counters first or the first one found
       
  3326 
       
  3327     const TTime nullTime = Time::NullTTime();
       
  3328     TTime oldTime = nullTime;
       
  3329     TTime newTime = nullTime;
       
  3330     TTime oldTimePos = nullTime;
       
  3331     TTime newTimePos = nullTime;
       
  3332 
       
  3333     // 1. Full
       
  3334     // If the old or new one is the ultimate one, don't bother to
       
  3335     // check anything else.
       
  3336     if ( aOldOne.iActiveConstraints == EConstraintNone )
       
  3337         {
       
  3338         return EFalse;
       
  3339         }
       
  3340 
       
  3341     if ( aNewOne.iActiveConstraints == EConstraintNone )
       
  3342         {
       
  3343         return ETrue;
       
  3344         }
       
  3345 
       
  3346     // 2. Start & End Time
       
  3347     // Choose the one with the closest end time first
       
  3348     // All RO's to this check are already checked to be valid
       
  3349     // ActiveIntervals Also hit this spot
       
  3350 
       
  3351     // First get the start and end times from the intervals if they are active or inactive:
       
  3352     if ( aOldOne.iActiveConstraints & EConstraintInterval )
       
  3353         {
       
  3354         if( aOldOne.iIntervalStart == nullTime )
       
  3355             {
       
  3356             oldTimePos = iTrustedTime;
       
  3357             oldTimePos += TTimeIntervalSeconds( aOldOne.iInterval );
       
  3358             }
       
  3359         else
       
  3360             {
       
  3361             oldTime = aOldOne.iIntervalStart;
       
  3362             oldTime += TTimeIntervalSeconds( aOldOne.iInterval );
       
  3363             }
       
  3364         }
       
  3365 
       
  3366     if( aNewOne.iActiveConstraints & EConstraintInterval )
       
  3367         {
       
  3368         if( aNewOne.iIntervalStart == nullTime )
       
  3369             {
       
  3370             newTimePos = iTrustedTime;
       
  3371             newTimePos += TTimeIntervalSeconds( aNewOne.iInterval );
       
  3372             }
       
  3373         else
       
  3374             {
       
  3375             newTime = aNewOne.iIntervalStart;
       
  3376             newTime += TTimeIntervalSeconds( aNewOne.iInterval );
       
  3377             }
       
  3378         }
       
  3379 
       
  3380     if ( aOldOne.iActiveConstraints & EConstraintEndTime || oldTime != nullTime )
       
  3381         {
       
  3382         oldTime = EndTime( oldTime, aOldOne.iEndTime );
       
  3383 
       
  3384         if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime )
       
  3385             {
       
  3386             newTime = EndTime( newTime, aNewOne.iEndTime );
       
  3387 
       
  3388             if( newTime != oldTime )
       
  3389                 {
       
  3390                 return ( newTime < oldTime );
       
  3391                 }
       
  3392             }
       
  3393         else
       
  3394             {
       
  3395             return EFalse;
       
  3396             }
       
  3397         }
       
  3398     else if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime )
       
  3399         {
       
  3400         return ETrue;
       
  3401         }
       
  3402 
       
  3403 
       
  3404     // 3. Inactive Intervals:
       
  3405     // Choose the one with the interval ending first:
       
  3406     // Continue here if the no SE's exist or SE's are the same
       
  3407     if( aOldOne.iActiveConstraints & EConstraintInterval )
       
  3408         {
       
  3409         if( aNewOne.iActiveConstraints & EConstraintInterval )
       
  3410             {
       
  3411             oldTimePos = EndTime( oldTime, oldTimePos );
       
  3412             newTimePos = EndTime( newTime, newTimePos );
       
  3413 
       
  3414             if( oldTimePos != newTimePos )
       
  3415                 {
       
  3416                 return ( newTimePos < oldTimePos );
       
  3417                 }
       
  3418             }
       
  3419         else
       
  3420             {
       
  3421             if( aNewOne.iActiveConstraints & EConstraintAccumulated ||
       
  3422                 aNewOne.iActiveConstraints & EConstraintTimedCounter ||
       
  3423                 aNewOne.iActiveConstraints & EConstraintCounter )
       
  3424                 {
       
  3425                 return EFalse;
       
  3426                 }
       
  3427             else
       
  3428                 {
       
  3429                 return ETrue;
       
  3430                 }
       
  3431             }
       
  3432         }
       
  3433     else if( aNewOne.iActiveConstraints & EConstraintInterval )
       
  3434         {
       
  3435         if( aOldOne.iActiveConstraints & EConstraintAccumulated ||
       
  3436             aOldOne.iActiveConstraints & EConstraintTimedCounter ||
       
  3437             aOldOne.iActiveConstraints & EConstraintCounter )
       
  3438             {
       
  3439             return ETrue;
       
  3440             }
       
  3441         else
       
  3442             {
       
  3443             return EFalse;
       
  3444             }
       
  3445         }
       
  3446 
       
  3447     // 4. Accumulated:
       
  3448     // Choose the shortest accumulated first
       
  3449     // Continue here if SE's or intervals do not exist or they are the same
       
  3450     if( aOldOne.iActiveConstraints & EConstraintAccumulated )
       
  3451         {
       
  3452         if( aNewOne.iActiveConstraints & EConstraintAccumulated )
       
  3453             {
       
  3454             if( aNewOne.iAccumulatedTime != aOldOne.iAccumulatedTime )
       
  3455                 {
       
  3456                 return ( aNewOne.iAccumulatedTime < aOldOne.iAccumulatedTime );
       
  3457                 }
       
  3458             }
       
  3459         else
       
  3460             {
       
  3461             if( aNewOne.iActiveConstraints & EConstraintTimedCounter ||
       
  3462                 aNewOne.iActiveConstraints & EConstraintCounter )
       
  3463                 {
       
  3464                 return EFalse;
       
  3465                 }
       
  3466             else
       
  3467                 {
       
  3468                 return ETrue;
       
  3469                 }
       
  3470             }
       
  3471         }
       
  3472     else if( aNewOne.iActiveConstraints & EConstraintAccumulated )
       
  3473         {
       
  3474         if( aOldOne.iActiveConstraints & EConstraintTimedCounter ||
       
  3475             aOldOne.iActiveConstraints & EConstraintCounter )
       
  3476             {
       
  3477             return ETrue;
       
  3478             }
       
  3479         else
       
  3480             {
       
  3481             return EFalse;
       
  3482             }
       
  3483         }
       
  3484 
       
  3485 
       
  3486     // 5. Timed Counter
       
  3487     // Choose the one with least counters first. If there is an equal number of counters
       
  3488     // left, use the one with the longest time
       
  3489     // Continue here if SE's or intervals or accumulateds do not exist or they are the same
       
  3490     if( aOldOne.iActiveConstraints & EConstraintTimedCounter )
       
  3491         {
       
  3492         if( aNewOne.iActiveConstraints & EConstraintTimedCounter )
       
  3493             {
       
  3494             if( aNewOne.iTimedCounter == aOldOne.iTimedCounter )
       
  3495                 {
       
  3496                 if( aNewOne.iTimedInterval != aOldOne.iTimedInterval )
       
  3497                     {
       
  3498                     return ( aNewOne.iTimedInterval < aOldOne.iTimedInterval );
       
  3499                     }
       
  3500                 else
       
  3501                     {
       
  3502                     if( aNewOne.iActiveConstraints & EConstraintCounter )
       
  3503                         {
       
  3504 
       
  3505                         }
       
  3506                     }
       
  3507                 }
       
  3508             else
       
  3509                 {
       
  3510                 return ( aNewOne.iTimedCounter < aOldOne.iTimedCounter );
       
  3511                 }
       
  3512 
       
  3513             }
       
  3514         else
       
  3515             {
       
  3516             if( aNewOne.iActiveConstraints & EConstraintCounter )
       
  3517                 {
       
  3518                 return EFalse;
       
  3519                 }
       
  3520             else
       
  3521                 {
       
  3522                 return ETrue;
       
  3523                 }
       
  3524             }
       
  3525         }
       
  3526     else if( aNewOne.iActiveConstraints & EConstraintTimedCounter )
       
  3527         {
       
  3528         if( aOldOne.iActiveConstraints & EConstraintCounter )
       
  3529             {
       
  3530             return ETrue;
       
  3531             }
       
  3532         else
       
  3533             {
       
  3534             return EFalse;
       
  3535             }
       
  3536         }
       
  3537 
       
  3538     // 6. Counter
       
  3539     // Choose the one with least counters:
       
  3540     // if they are the same choose the first one.
       
  3541     // Continue here if SE's or intervals or accumulateds or timed counters
       
  3542     // do not exist or they are the same
       
  3543     if( aOldOne.iActiveConstraints & EConstraintCounter )
       
  3544         {
       
  3545         if( aNewOne.iActiveConstraints & EConstraintCounter )
       
  3546             {
       
  3547             return ( aNewOne.iCounter < aOldOne.iCounter );
       
  3548             }
       
  3549         else
       
  3550             {
       
  3551             return ETrue;
       
  3552             }
       
  3553         }
       
  3554 
       
  3555     // If all else fails use the old one:
       
  3556     return EFalse;
       
  3557     }
       
  3558 
       
  3559 
       
  3560 // -----------------------------------------------------------------------------
       
  3561 // CDRMDbSession::BetterPermission
       
  3562 // Compares two permissions, and returns ETrue if aNewOne is more suitable
       
  3563 // for the usage. Assumes both are valid, i.e. not expired.
       
  3564 // -----------------------------------------------------------------------------
       
  3565 TBool BetterPermissionOld( const CDRMConstraint& aNewOne,
       
  3566     const CDRMConstraint& aOldOne ) //const
       
  3567     {
       
  3568 
       
  3569     const TTime nullTime = Time::NullTTime();
       
  3570     TTime oldTime = nullTime;
       
  3571     TTime newTime = nullTime;
       
  3572     TBool inactiveIntervals = EFalse;
       
  3573 
       
  3574     // If the old or new one is the ultimate one, don't bother to
       
  3575     // check anything else.
       
  3576     if ( aOldOne.iActiveConstraints == EConstraintNone )
       
  3577         {
       
  3578         return EFalse;
       
  3579         }
       
  3580 
       
  3581     if ( aNewOne.iActiveConstraints == EConstraintNone )
       
  3582         {
       
  3583         return ETrue;
       
  3584         }
       
  3585 
       
  3586     // If old one has count constraints but the new doesn't, the new
       
  3587     // is better. If the old one doesn't have counters but the
       
  3588     // new has, the old one is better.
       
  3589     if ( aOldOne.iActiveConstraints & EConstraintCounter )
       
  3590         {
       
  3591         if ( !( aNewOne.iActiveConstraints & EConstraintCounter ) ||
       
  3592              ( aNewOne.iCounter < aOldOne.iCounter ) )
       
  3593             {
       
  3594             return ETrue;
       
  3595             }
       
  3596         }
       
  3597     else
       
  3598         {
       
  3599         if ( aNewOne.iActiveConstraints & EConstraintCounter )
       
  3600             {
       
  3601             return EFalse;
       
  3602             }
       
  3603         }
       
  3604 
       
  3605     if ( aOldOne.iActiveConstraints & EConstraintTimedCounter )
       
  3606         {
       
  3607         if ( !( aNewOne.iActiveConstraints & EConstraintTimedCounter ) ||
       
  3608              ( aNewOne.iTimedCounter < aOldOne.iTimedCounter ) )
       
  3609             {
       
  3610             return ETrue;
       
  3611             }
       
  3612         }
       
  3613     else
       
  3614         {
       
  3615         if ( aNewOne.iActiveConstraints & EConstraintTimedCounter )
       
  3616             {
       
  3617             return EFalse;
       
  3618             }
       
  3619         }
       
  3620 
       
  3621     if ( aOldOne.iActiveConstraints & EConstraintAccumulated )
       
  3622         {
       
  3623         if ( !( aNewOne.iActiveConstraints & EConstraintAccumulated ) ||
       
  3624              ( aNewOne.iAccumulatedTime < aOldOne.iAccumulatedTime ) )
       
  3625             {
       
  3626             return ETrue;
       
  3627             }
       
  3628         }
       
  3629     else
       
  3630         {
       
  3631         if ( aNewOne.iActiveConstraints & EConstraintAccumulated )
       
  3632             {
       
  3633             return EFalse;
       
  3634             }
       
  3635         }
       
  3636 
       
  3637     // - No intervals is better than inactive intervals.
       
  3638     // - No intervals compared to activated interval goes to
       
  3639     //   end time constraint comparison.
       
  3640     // - Activated interval is better than inactive interval.
       
  3641     // - Two inactive intervals go to end time constraint comparison.
       
  3642     if ( aOldOne.iActiveConstraints & EConstraintInterval )
       
  3643         {
       
  3644         if ( aNewOne.iActiveConstraints & EConstraintInterval )
       
  3645             {
       
  3646             if ( aOldOne.iIntervalStart == nullTime )
       
  3647                 {
       
  3648                 if ( aNewOne.iIntervalStart != nullTime )
       
  3649                     {
       
  3650                     return ETrue;
       
  3651                     }
       
  3652 
       
  3653                 // Both have inactive intervals.
       
  3654                 inactiveIntervals = ETrue;
       
  3655 
       
  3656 //                oldTime = iTrustedTime;
       
  3657                 oldTime += TTimeIntervalSeconds( aOldOne.iInterval );
       
  3658 
       
  3659 //                newTime = iTrustedTime;
       
  3660                 newTime += TTimeIntervalSeconds( aNewOne.iInterval );
       
  3661                 }
       
  3662             else
       
  3663                 {
       
  3664                 // Old one has activated interval.
       
  3665                 if ( aNewOne.iIntervalStart == nullTime )
       
  3666                     {
       
  3667                     return EFalse;
       
  3668                     }
       
  3669 
       
  3670                 // Both have activated intervals.
       
  3671                 oldTime = aOldOne.iIntervalStart;
       
  3672                 oldTime += TTimeIntervalSeconds( aOldOne.iInterval );
       
  3673 
       
  3674                 newTime = aNewOne.iIntervalStart;
       
  3675                 newTime += TTimeIntervalSeconds( aNewOne.iInterval );
       
  3676                 }
       
  3677             }
       
  3678         else
       
  3679             {
       
  3680             // No intervals in the new one.
       
  3681             if ( aOldOne.iIntervalStart == nullTime )
       
  3682                 {
       
  3683                 return ETrue;
       
  3684                 }
       
  3685 
       
  3686             oldTime = aOldOne.iIntervalStart;
       
  3687             oldTime += TTimeIntervalSeconds( aOldOne.iInterval );
       
  3688             }
       
  3689         }
       
  3690     else
       
  3691         {
       
  3692         // The old one doesn't have intervals.
       
  3693         if ( aNewOne.iActiveConstraints & EConstraintInterval )
       
  3694             {
       
  3695             if ( aNewOne.iIntervalStart == nullTime )
       
  3696                 {
       
  3697                 return EFalse;
       
  3698                 }
       
  3699 
       
  3700             newTime = aNewOne.iIntervalStart + TTimeIntervalSeconds( aNewOne.iInterval );
       
  3701             }
       
  3702         }
       
  3703 
       
  3704     if ( inactiveIntervals )
       
  3705         {
       
  3706         // The one with end time goes first.
       
  3707         if ( aOldOne.iActiveConstraints & EConstraintEndTime )
       
  3708             {
       
  3709             if ( aNewOne.iActiveConstraints & EConstraintEndTime )
       
  3710                 {
       
  3711                 oldTime = EndTime( oldTime, aOldOne.iEndTime );
       
  3712                 newTime = EndTime( newTime, aNewOne.iEndTime );
       
  3713 
       
  3714                 return ( newTime < oldTime );
       
  3715                 }
       
  3716 
       
  3717             return EFalse;
       
  3718             }
       
  3719 
       
  3720         if( aNewOne.iActiveConstraints & EConstraintEndTime )
       
  3721             {
       
  3722             return ETrue;
       
  3723             }
       
  3724 
       
  3725         // Both have just inactive intervals.
       
  3726         return ( newTime < oldTime );
       
  3727         }
       
  3728 
       
  3729     // Check end times and/or activated intervals.
       
  3730     if ( aOldOne.iActiveConstraints & EConstraintEndTime || oldTime != nullTime )
       
  3731         {
       
  3732         oldTime = EndTime( oldTime, aOldOne.iEndTime );
       
  3733 
       
  3734         if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime )
       
  3735             {
       
  3736             newTime = EndTime( newTime, aNewOne.iEndTime );
       
  3737 
       
  3738             return ( newTime < oldTime );
       
  3739             }
       
  3740 
       
  3741         // The new one doesn't have end time constraint and/or activated intervals.
       
  3742         return EFalse;
       
  3743         }
       
  3744 
       
  3745     if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime )
       
  3746         {
       
  3747         return ETrue;
       
  3748         }
       
  3749 
       
  3750     // Start time does not expire, so let's keep the old one.
       
  3751 
       
  3752     return EFalse;
       
  3753     }
       
  3754 
       
  3755 
       
  3756 // ----------------------------------------------------------------------------
       
  3757 // UnwrapProtectedCekL
       
  3758 // Unwraps the protected CEK aProtectedCek. Caller owns the returned buffer.
       
  3759 // ----------------------------------------------------------------------------
       
  3760 //
       
  3761 HBufC8* CDRMDbSession::UnwrapProtectedCekL(
       
  3762     const TDesC8& aProtectedCek )
       
  3763     {
       
  3764     MDrmKeyStorage* storage;
       
  3765     TBuf8<OmaCrypto::KMacSize> mac;
       
  3766     TBuf8<OmaCrypto::KKeySize> rek;
       
  3767     HBufC8* cek = NULL;
       
  3768     TPtrC8 macAndRek(0, 0);
       
  3769     TPtrC8 wrappedCek(0, 0);
       
  3770     TKeyTransportScheme transport;
       
  3771     TBuf8<KRiIdSize> rightsIssuer;
       
  3772     CDRMRIContext* riContext = NULL;
       
  3773     TInt i;
       
  3774     TInt len;
       
  3775 
       
  3776     DRMLOG(_L("CDRMDbSession::UnwrapProtectedCekL"));
       
  3777 
       
  3778     // first element: one byte for the transport scheme
       
  3779     i = 0;
       
  3780     transport = static_cast<TKeyTransportScheme>(aProtectedCek[i]);
       
  3781     i++;
       
  3782 
       
  3783     DRMLOG2(_L("Transport scheme: %d"), transport);
       
  3784 
       
  3785     // second element: the concatenated MAC and REK wrapped with the KEK
       
  3786     len = aProtectedCek[i];
       
  3787     macAndRek.Set(aProtectedCek.Mid(i + 1, len));
       
  3788     i = i + 1 + len;
       
  3789     DRMLOG(_L("MAC + REK:"));
       
  3790     DRMLOGHEX(macAndRek);
       
  3791 
       
  3792     // third element: 20 bytes with the rights issuer ID
       
  3793     len = aProtectedCek[i];
       
  3794     rightsIssuer.Copy(aProtectedCek.Mid(i + 1, len));
       
  3795     i = i + 1 + len;
       
  3796     DRMLOG(_L("RI ID:"));
       
  3797     DRMLOGHEX(rightsIssuer);
       
  3798 
       
  3799     // get the trusted root from the rights issuer context
       
  3800     if ( !iRoapClientConnected )
       
  3801         {
       
  3802         User::LeaveIfError( iRoapClient.Connect() );
       
  3803         iRoapClientConnected = ETrue;
       
  3804         }
       
  3805     riContext = iRoapClient.GetRIContextL(rightsIssuer);
       
  3806     if ( !riContext )
       
  3807         {
       
  3808         DRMLOG(_L("RI not registered"));
       
  3809         User::Leave(KErrRightsServerRiNotRegistered);
       
  3810         }
       
  3811     CleanupStack::PushL(riContext);
       
  3812 
       
  3813     // connect to the storage of our PKI keys
       
  3814     storage = DrmKeyStorageNewL();
       
  3815     TCleanupItem storageCleanup( DeleteObject, storage );
       
  3816     CleanupStack::PushL(storageCleanup);
       
  3817     storage->SelectTrustedRootL(riContext->SelectedDeviceRoot());
       
  3818 
       
  3819     if (transport == EOma)
       
  3820         {
       
  3821         OmaCrypto::RsaKemKwsDecryptL(storage, macAndRek, rek, mac);
       
  3822         }
       
  3823     else
       
  3824         {
       
  3825         CmlaCrypto::CmlaIpDecryptL(transport, storage, macAndRek, rek, mac);
       
  3826         }
       
  3827 
       
  3828     DRMLOG(_L("REK:"));
       
  3829     DRMLOGHEX(rek);
       
  3830     DRMLOG(_L("MAC:"));
       
  3831     DRMLOGHEX(mac);
       
  3832 
       
  3833     iMac.Copy(mac);
       
  3834     iRek.Copy(rek);
       
  3835 
       
  3836     // fourth element: 24 bytes for the CEK (wrapped with the REK),
       
  3837     // this can be empty, e.g. for a parent RO (indicated by a zero length)
       
  3838     len = aProtectedCek[i];
       
  3839     if (len > 0)
       
  3840         {
       
  3841         wrappedCek.Set(aProtectedCek.Mid(i + 1, len));
       
  3842         DRMLOG(_L("Wrapped CEK:"));
       
  3843         DRMLOGHEX(wrappedCek);
       
  3844         cek = OmaCrypto::AesUnwrapL(rek, wrappedCek);
       
  3845         DRMLOG(_L("CEK:"));
       
  3846         DRMLOGHEX(( *cek ));
       
  3847         }
       
  3848     else
       
  3849         {
       
  3850         DRMLOG(_L("No CEK"));
       
  3851         cek = KNullDesC8().AllocL();
       
  3852         }
       
  3853 
       
  3854     CleanupStack::PopAndDestroy(2); // riContext, storageCleanup
       
  3855     return cek;
       
  3856     }
       
  3857 
       
  3858 // ----------------------------------------------------------------------------
       
  3859 // UnwrapDomainCekL
       
  3860 // Unwraps CEK with is wrapped with a domain key. Caller owns the returned
       
  3861 // buffer.
       
  3862 // ----------------------------------------------------------------------------
       
  3863 //
       
  3864 HBufC8* CDRMDbSession::UnwrapDomainCekL(
       
  3865     const TDesC8& aProtectedCek,
       
  3866     const TDesC8& aDomainId )
       
  3867     {
       
  3868     HBufC8* unwrappedMacAndRek = NULL;
       
  3869     HBufC8* cek = NULL;
       
  3870     TPtrC8 macAndRek(0, 0);
       
  3871     TPtrC8 wrappedCek(0, 0);
       
  3872     CDRMDomainContext* domainContext;
       
  3873     HBufC8* domainKey = NULL;
       
  3874     TInt i;
       
  3875     TInt len;
       
  3876 
       
  3877     DRMLOG(_L("CDRMDbSession::UnwrapDomainCekL"));
       
  3878 
       
  3879     // first element (one byte for the transport scheme) is ignored
       
  3880     i = 1;
       
  3881 
       
  3882     // second element: MAC and REK wrapped with the domain key (40 bytes)
       
  3883     len = aProtectedCek[i];
       
  3884     macAndRek.Set(aProtectedCek.Mid(i + 1, len));
       
  3885     i = i + 1 + len;
       
  3886     DRMLOG(_L("MAC + REK:"));
       
  3887     DRMLOGHEX(macAndRek);
       
  3888 
       
  3889     // third element: 20 bytes with the rights issuer ID, is ignored
       
  3890     len = aProtectedCek[i];
       
  3891     i = i + 1 + len;
       
  3892 
       
  3893     // fourth element: 24 bytes for the CEK (wrapped with the REK)
       
  3894     len = aProtectedCek[i];
       
  3895     wrappedCek.Set(aProtectedCek.Mid(i + 1, len));
       
  3896     DRMLOG(_L("Wrapped CEK:"));
       
  3897     DRMLOGHEX(wrappedCek);
       
  3898 
       
  3899     // get the domain key from the domain context
       
  3900     if ( !iRoapClientConnected )
       
  3901         {
       
  3902         User::LeaveIfError( iRoapClient.Connect() );
       
  3903         iRoapClientConnected = ETrue;
       
  3904         }
       
  3905     domainContext = iRoapClient.GetDomainContextL(aDomainId);
       
  3906     if ( !domainContext )
       
  3907         {
       
  3908         DRMLOG(_L("Domain not registered"));
       
  3909         User::Leave(KErrRightsServerDomainNotRegistered);
       
  3910         }
       
  3911     CleanupStack::PushL(domainContext);
       
  3912 
       
  3913     // last three digits presents the domain generation
       
  3914     TInt generation = 0;
       
  3915     TLex8 lex( aDomainId.Right(3));
       
  3916     lex.Val(generation);
       
  3917 
       
  3918     domainKey = domainContext->DomainKeyL(generation);
       
  3919     CleanupStack::PushL( domainKey );
       
  3920 
       
  3921     // unwrap MAC and REK first with the domain key, the CEK with REK
       
  3922     unwrappedMacAndRek = OmaCrypto::AesUnwrapL(*domainKey, macAndRek);
       
  3923     CleanupStack::PushL(unwrappedMacAndRek);
       
  3924     cek = OmaCrypto::AesUnwrapL(unwrappedMacAndRek->Right(
       
  3925             OmaCrypto::KKeySize), wrappedCek);
       
  3926     iMac.Copy( unwrappedMacAndRek->Left( OmaCrypto::KKeySize) );
       
  3927     CleanupStack::PopAndDestroy(3); // unwrappedMacAndRek, domainKey, domainContext
       
  3928 
       
  3929     return cek;
       
  3930     }
       
  3931 
       
  3932 // ----------------------------------------------------------------------------
       
  3933 // CDRMDbSession::VerifyCredentials
       
  3934 // Check if the client has enough credentials to grant access to later
       
  3935 // decryption.
       
  3936 // ----------------------------------------------------------------------------
       
  3937 //
       
  3938 TInt CDRMDbSession::VerifyCredentials(
       
  3939     HBufC8* aContentId,
       
  3940     CDRMPermission* aPermission,
       
  3941     TIntent aIntent)
       
  3942     {
       
  3943     CDRMConstraint* constraint = NULL;
       
  3944     _LIT_SECURITY_POLICY_C1(drmCheck, ECapabilityDRM);
       
  3945     _LIT_SECURITY_POLICY_V0(vidCheck, VID_DEFAULT); // Check Default VID
       
  3946     RPointerArray<CDRMPermission> permissions;
       
  3947     TInt r = KErrAccessDenied;
       
  3948     TBool hasOma2Permissions = EFalse;
       
  3949     TBool hasSoftwareConstraints = EFalse;
       
  3950     TInt i;
       
  3951 
       
  3952     __UHEAP_MARK;
       
  3953     // Get the applicable permission, and check if there are OMA 2 permissions or
       
  3954     // software constraints
       
  3955     if (aPermission)
       
  3956         {
       
  3957         constraint = aPermission->ConstraintForIntent(aIntent);
       
  3958         }
       
  3959     if ( aContentId )
       
  3960         {
       
  3961         TRAP_IGNORE( DRMDB.GetDBEntryByContentIDL(*aContentId, permissions) );
       
  3962         for (i = 0; i < permissions.Count(); i++)
       
  3963             {
       
  3964             if (permissions[i]->iRightsObjectVersion.iVersionMain == EOma2Rights ||
       
  3965                 permissions[i]->iRightsObjectVersion.iVersionMain == ECmlaRights)
       
  3966                 {
       
  3967                 hasOma2Permissions = ETrue;
       
  3968                 }
       
  3969             if (permissions[i]->SoftwareConstrained())
       
  3970                 {
       
  3971                 hasSoftwareConstraints = ETrue;
       
  3972                 }
       
  3973             }
       
  3974         permissions.ResetAndDestroy();
       
  3975         permissions.Close();
       
  3976         }
       
  3977 
       
  3978     // First, check for DRM capability, access granted only if there are no software
       
  3979     // constraints.
       
  3980     if (drmCheck().CheckPolicy(iClient) && !hasSoftwareConstraints)
       
  3981         {
       
  3982         r = KErrNone;
       
  3983         }
       
  3984 
       
  3985     // If a permission is given, check for license manager cases as well as
       
  3986     // OMA DRM 1.0 case
       
  3987     if ( r != KErrNone && aPermission )
       
  3988         {
       
  3989         // Fallback: Check if the vendor ID is the default vendor ID,
       
  3990         // allow access for OMA DRM 1.0 rights
       
  3991         if ((aPermission->iRightsObjectVersion.iVersionMain == EOma1Rights &&
       
  3992              vidCheck().CheckPolicy(iClient)))
       
  3993             {
       
  3994             r = KErrNone;
       
  3995             }
       
  3996 
       
  3997         // Check the software constraint, this can override the fallback above!
       
  3998         if ( constraint )
       
  3999             {
       
  4000             _LIT_SECURITY_POLICY_S0(swSidCheck, constraint->iSecureId.iUid);
       
  4001             _LIT_SECURITY_POLICY_V0(swVidCheck, constraint->iVendorId.iUid);
       
  4002             if (constraint->iActiveConstraints & EConstraintVendor)
       
  4003                 {
       
  4004                 if (swVidCheck().CheckPolicy(iClient))
       
  4005                     {
       
  4006                     r = KErrNone;
       
  4007                     }
       
  4008                 else
       
  4009                     {
       
  4010                     r = KErrAccessDenied;
       
  4011                     }
       
  4012                 }
       
  4013             if (constraint->iActiveConstraints & EConstraintSoftware)
       
  4014                 {
       
  4015                 if (swSidCheck().CheckPolicy(iClient))
       
  4016                     {
       
  4017                     r = KErrNone;
       
  4018                     }
       
  4019                 else
       
  4020                     {
       
  4021                     r = KErrAccessDenied;
       
  4022                     }
       
  4023                 }
       
  4024             }
       
  4025 
       
  4026         }
       
  4027 
       
  4028     // Application installer needs to be able to use the content even if it has SW constraints
       
  4029     _LIT_SECURITY_POLICY_S0(swSidCheck2, KAppInstSrv);
       
  4030 
       
  4031     if( swSidCheck2().CheckPolicy(iClient) && hasSoftwareConstraints )
       
  4032         {
       
  4033         r = KErrNone;
       
  4034         }
       
  4035 
       
  4036 
       
  4037     // Check if access can be granted when only
       
  4038     // OMA DRM 1.0 permissions are currently available, and the client
       
  4039     // has the default vendor ID
       
  4040     if ( r != KErrNone && !hasOma2Permissions &&
       
  4041         !hasSoftwareConstraints && vidCheck().CheckPolicy( iClient ) )
       
  4042         {
       
  4043         r = KErrNone;
       
  4044         }
       
  4045     __UHEAP_MARKEND;
       
  4046 
       
  4047     if ( r == KErrNone )
       
  4048         {
       
  4049         iCredentialsChecked = ECheckedAndAllowed;
       
  4050         }
       
  4051     else
       
  4052         {
       
  4053         iCredentialsChecked = ECheckedAndDenied;
       
  4054         }
       
  4055     return r;
       
  4056     }
       
  4057 
       
  4058 // ----------------------------------------------------------------------------
       
  4059 // CDRMDbSession::RemoveInvalidPermissionsL
       
  4060 // Remove all permissions where the domain context is not available
       
  4061 // ----------------------------------------------------------------------------
       
  4062 //
       
  4063 void CDRMDbSession::RemoveInvalidPermissionsL(
       
  4064     CDRMPermissionList* aList )
       
  4065     {
       
  4066     CDRMDomainContext* domainContext = NULL;
       
  4067     TInt i;
       
  4068     if ( !iRoapClientConnected )
       
  4069         {
       
  4070         User::LeaveIfError( iRoapClient.Connect() );
       
  4071         iRoapClientConnected = ETrue;
       
  4072         }
       
  4073     for ( i = aList->Count() - 1; i >= 0; i-- )
       
  4074         {
       
  4075         if ( (*aList)[i]->iDomainID )
       
  4076             {
       
  4077             domainContext = iRoapClient.GetDomainContextL(
       
  4078                 *(*aList)[i]->iDomainID );
       
  4079             if ( domainContext )
       
  4080                 {
       
  4081                 delete domainContext;
       
  4082                 }
       
  4083             else
       
  4084                 {
       
  4085                 aList->Remove( i );
       
  4086                 }
       
  4087             }
       
  4088         }
       
  4089     }
       
  4090 
       
  4091 // ----------------------------------------------------------------------------
       
  4092 // CDRMDbSession::
       
  4093 //
       
  4094 // ----------------------------------------------------------------------------
       
  4095 //
       
  4096 void CDRMDbSession::SetNameL( const RMessage2& aMessage )
       
  4097     {
       
  4098     DRMLOG( _L( "CDRMDbSession::SetNameL" ) );
       
  4099     __UHEAP_MARK;
       
  4100 
       
  4101     SanitizeL( aMessage.GetDesLength( 0 ) );
       
  4102     SanitizeL( aMessage.GetDesLength( 1 ) );
       
  4103 
       
  4104     TInt namelength = User::LeaveIfError( IPCGETDESLEN1 );
       
  4105     HBufC8* cid = HBufC8::NewLC( IPCGETDESLEN0 );
       
  4106     HBufC* name = HBufC::NewLC( namelength > 0 ? namelength : 1 );
       
  4107     TPtr8 tmp( cid->Des() );
       
  4108 
       
  4109     IPCREAD0L( tmp );
       
  4110     if ( namelength )
       
  4111         {
       
  4112         TPtr tmp2( name->Des() );
       
  4113         IPCREAD1L( tmp2 );
       
  4114         }
       
  4115 
       
  4116     DRMDB.NameContentL( *cid, *name );
       
  4117 
       
  4118     CleanupStack::PopAndDestroy( 2 );
       
  4119     __UHEAP_MARKEND;
       
  4120     aMessage.Complete( KErrNone );
       
  4121     }
       
  4122 
       
  4123 // ----------------------------------------------------------------------------
       
  4124 // CDRMDbSession::
       
  4125 //
       
  4126 // ----------------------------------------------------------------------------
       
  4127 //
       
  4128 void CDRMDbSession::GetNameL( const RMessage2& aMessage )
       
  4129     {
       
  4130     DRMLOG( _L( "CDRMDbSession::GetNameL" ) );
       
  4131     HBufC8* cid = NULL;
       
  4132     TPckgBuf< TInt > size( 0 );
       
  4133 
       
  4134     // Cleanup.
       
  4135     if ( iWidePreparedData )
       
  4136         {
       
  4137         delete iWidePreparedData;
       
  4138         iWidePreparedData = NULL;
       
  4139         }
       
  4140 
       
  4141     SanitizeL( aMessage.GetDesLength( 0 ) );
       
  4142     cid = HBufC8::NewLC( IPCGETDESLEN0 );
       
  4143     TPtr8 tmp( cid->Des() );
       
  4144     IPCREAD0L( tmp );
       
  4145 
       
  4146     iWidePreparedData = DRMDB.ContentNameLC( *cid );
       
  4147 
       
  4148     CleanupStack::Pop( iWidePreparedData );
       
  4149     CleanupStack::PopAndDestroy( cid );
       
  4150 
       
  4151     size() = iWidePreparedData->Length();
       
  4152     if ( iWidePreparedData->Length() == 0 )
       
  4153         {
       
  4154         // Empty name --> not asked.
       
  4155         delete iWidePreparedData;
       
  4156         iWidePreparedData = NULL;
       
  4157         }
       
  4158 
       
  4159     IPCWRITE1L( size );
       
  4160 
       
  4161     aMessage.Complete( KErrNone );
       
  4162     }
       
  4163 
       
  4164 // ----------------------------------------------------------------------------
       
  4165 // CDRMDbSession::
       
  4166 //
       
  4167 // ----------------------------------------------------------------------------
       
  4168 //
       
  4169 void CDRMDbSession::GetWideDataL( const RMessage2& aMessage )
       
  4170     {
       
  4171     DRMLOG( _L( "CDRMDbSesion::GetWideDataL" ) );
       
  4172     if ( iWidePreparedData )
       
  4173         {
       
  4174         if( iWidePreparedData->Length() > aMessage.GetDesMaxLength(0) )
       
  4175             {
       
  4176             User::Leave(KErrArgument);
       
  4177             }
       
  4178 
       
  4179         IPCWRITE0L( *iWidePreparedData );
       
  4180 
       
  4181         delete iWidePreparedData;
       
  4182         iWidePreparedData = NULL;
       
  4183 
       
  4184         aMessage.Complete( KErrNone );
       
  4185         return;
       
  4186         }
       
  4187 
       
  4188     aMessage.Complete( KErrNotReady );
       
  4189     }
       
  4190 
       
  4191 // ----------------------------------------------------------------------------
       
  4192 // CDRMDbSession::
       
  4193 //
       
  4194 // ----------------------------------------------------------------------------
       
  4195 //
       
  4196 void CDRMDbSession::Cancel( const RMessage2& aMessage )
       
  4197     {
       
  4198     DRMLOG( _L( "CDRMDbSession::Cancel" ) );
       
  4199     if ( iPendingRequest )
       
  4200         {
       
  4201         static_cast<CDRMActiveOperation*>(iPendingRequest)->Remove();
       
  4202         }
       
  4203 
       
  4204     aMessage.Complete( KErrNone );
       
  4205     }
       
  4206 
       
  4207 // ----------------------------------------------------------------------------
       
  4208 // CDRMDbSession::
       
  4209 //
       
  4210 // ----------------------------------------------------------------------------
       
  4211 //
       
  4212 void CDRMDbSession::GetFLUriL( const RMessage2& aMessage )
       
  4213     {
       
  4214     DRMLOG( _L( "CDRMDbSession::GetFLUriL" ) );
       
  4215 
       
  4216     TBuf8< KMaxOmaV1CIDLength > URI;
       
  4217 
       
  4218     GetFlURI( URI );
       
  4219 
       
  4220     if( URI.Length() > aMessage.GetDesMaxLength(0) )
       
  4221         {
       
  4222         User::Leave(KErrArgument);
       
  4223         }
       
  4224 
       
  4225     IPCWRITE0L( URI );
       
  4226     aMessage.Complete( KErrNone );
       
  4227     }
       
  4228 
       
  4229 // ----------------------------------------------------------------------------
       
  4230 // CDRMDbSession::
       
  4231 //
       
  4232 // ----------------------------------------------------------------------------
       
  4233 //
       
  4234 void CDRMDbSession::EncodeRightsIssuerL( const RMessage2& aMessage )
       
  4235     {
       
  4236     __UHEAP_MARK;
       
  4237 
       
  4238     DRMLOG( _L( "CRMDbSession::EncodeRightsIssuerL" ) );
       
  4239     TBuf8< KDCFKeySize > iv;
       
  4240     HBufC8* data( NULL );
       
  4241     HBufC8* tmp( NULL );
       
  4242     iv.SetLength( KDCFKeySize );
       
  4243 
       
  4244     TInt size( User::LeaveIfError( IPCGETDESLEN0 ) );
       
  4245     TPtr8 des( NULL, 0, 0 );
       
  4246 
       
  4247     if ( size < 1 )
       
  4248         {
       
  4249         User::Leave( KErrArgument );
       
  4250         }
       
  4251 
       
  4252     // Calculate the size. It could be retrieved also from GetDesMaxLength,
       
  4253     // but at least now we can be sure we won't panic in case of
       
  4254     // descriptor overflow.
       
  4255     size += KDCFKeySize - ( size % KDCFKeySize ); //padding
       
  4256     size += KDCFKeySize; //iv
       
  4257     size = ( size + 2 ) / 3 * 4; //base64
       
  4258     size += IMEI.Length();
       
  4259     size += KFLPrefixLength;
       
  4260 
       
  4261     data = HBufC8::NewLC( size < KMaxOmaV1CIDLength ? KMaxOmaV1CIDLength : size );
       
  4262     des.Set( data->Des() );
       
  4263 
       
  4264     GetFlURI( des );
       
  4265 
       
  4266     tmp = DRMDB.GetDecryptionKeyL( *data );
       
  4267     CleanupStack::PushL( tmp );
       
  4268 
       
  4269     // Get the data from client.
       
  4270     IPCREAD0L( des );
       
  4271     GenerateIVL( iv );
       
  4272 
       
  4273     // Fits ok.
       
  4274     AesEncryptL( *tmp, iv, ETrue, des );
       
  4275 
       
  4276     CleanupStack::PopAndDestroy( tmp );
       
  4277 
       
  4278     // Fits ok.
       
  4279     des.Insert( 0, iv );
       
  4280 
       
  4281     tmp = Base64EncodeL( *data );
       
  4282 
       
  4283     __ASSERT_DEBUG( tmp->Length() + KFLPrefixLength + IMEI.Length() <= size,
       
  4284         User::Invariant() );
       
  4285 
       
  4286     // Overwrite the original data.
       
  4287     des = KFLPrefix;
       
  4288     des.Append( IMEI );
       
  4289     des.Append( *tmp );
       
  4290 
       
  4291     delete tmp;
       
  4292     tmp = NULL;
       
  4293 
       
  4294     IPCWRITE0L( *data );
       
  4295 
       
  4296     CleanupStack::PopAndDestroy( data );
       
  4297 
       
  4298     aMessage.Complete( KErrNone );
       
  4299 
       
  4300     __UHEAP_MARKEND;
       
  4301     }
       
  4302 
       
  4303 
       
  4304 // ----------------------------------------------------------------------------
       
  4305 // CDRMDbSession::
       
  4306 //
       
  4307 // ----------------------------------------------------------------------------
       
  4308 //
       
  4309 void CDRMDbSession::DecodeRightsIssuerL( const RMessage2& aMessage )
       
  4310     {
       
  4311     DRMLOG( _L( "CDRMDbSession::DecodeRightsIssuerL" ) );
       
  4312     __UHEAP_MARK;
       
  4313 
       
  4314     HBufC8* data( NULL );
       
  4315     TInt size( IPCGETDESLEN0 );
       
  4316     TPtr8 des( NULL, 0, 0 );
       
  4317 
       
  4318     if ( !size )
       
  4319         {
       
  4320         User::Leave( KErrArgument );
       
  4321         }
       
  4322 
       
  4323     SanitizeL( size );
       
  4324 
       
  4325     data = HBufC8::NewLC( size );
       
  4326     des.Set( data->Des() );
       
  4327 
       
  4328     IPCREAD0L( des );
       
  4329 
       
  4330     if ( des.Left( KFLPrefixLength ).Compare( KFLPrefix ) == 0 )
       
  4331         {
       
  4332         HBufC8* tmp( NULL );
       
  4333         HBufC8* tmp2( NULL );
       
  4334         TPtr8 des2( NULL, 0, 0 );
       
  4335 
       
  4336         tmp = CnvUtfConverter::ConvertFromUnicodeToUtf8L( IMEI );
       
  4337         CleanupStack::PushL( tmp );
       
  4338 
       
  4339         if ( des.Mid( KFLPrefixLength, IMEI.Length() ).Compare( *tmp ) )
       
  4340             {
       
  4341             User::Leave( KErrCANoPermission );
       
  4342             }
       
  4343 
       
  4344         tmp2 = Base64DecodeL( des.Mid( KFLPrefixLength + tmp->Length() ) );
       
  4345 
       
  4346         *data = *tmp2;
       
  4347 
       
  4348         delete tmp2;
       
  4349         tmp2 = NULL;
       
  4350 
       
  4351         CleanupStack::PopAndDestroy( tmp );
       
  4352 
       
  4353         if ( ( data->Length() % KDCFKeySize ) ||
       
  4354              data->Length() < ( KDCFKeySize << 1 ) )
       
  4355             {
       
  4356             User::Leave( KErrArgument );
       
  4357             }
       
  4358 
       
  4359         tmp = HBufC8::NewLC( KMaxOmaV1CIDLength );
       
  4360 
       
  4361         des.Set( tmp->Des() );
       
  4362 
       
  4363         GetFlURI( des );
       
  4364 
       
  4365         tmp2 = DRMDB.GetDecryptionKeyL( *tmp );
       
  4366 
       
  4367         CleanupStack::PopAndDestroy( tmp );
       
  4368         CleanupStack::PushL( tmp2 );
       
  4369 
       
  4370         des2.Set( const_cast< TText8* >( data->Ptr() ),
       
  4371             KDCFKeySize,
       
  4372             KDCFKeySize );
       
  4373 
       
  4374         // AesDecrypt overwrites the data.
       
  4375         des.Set( const_cast< TText8* >( data->Ptr() ) + KDCFKeySize,
       
  4376             data->Length() - KDCFKeySize,
       
  4377             data->Length() - KDCFKeySize );
       
  4378 
       
  4379         AesDecryptL( *tmp2, des2, ETrue, des );
       
  4380 
       
  4381         // Erase the key.
       
  4382         des2.Set( tmp2->Des() );
       
  4383         des2.FillZ();
       
  4384 
       
  4385         CleanupStack::PopAndDestroy( tmp2 );
       
  4386 
       
  4387         if( des.Length() > aMessage.GetDesMaxLength(1) )
       
  4388             {
       
  4389             User::Leave(KErrArgument);
       
  4390             }
       
  4391         IPCWRITE1L( des );
       
  4392         }
       
  4393 
       
  4394     // Something else, can't handle it. Leave it as it is.
       
  4395     CleanupStack::PopAndDestroy( data );
       
  4396 
       
  4397     aMessage.Complete( KErrNone );
       
  4398 
       
  4399     __UHEAP_MARKEND;
       
  4400 
       
  4401     DRMLOG( _L( "CDRMDbSession::DecodeRightsIssuerL ok" ) );
       
  4402     }
       
  4403 
       
  4404 // ----------------------------------------------------------------------------
       
  4405 // CDRMDbSession::
       
  4406 //
       
  4407 // ----------------------------------------------------------------------------
       
  4408 //
       
  4409 void CDRMDbSession::GetFlURI( TDes8& aURI )
       
  4410     {
       
  4411     aURI = KFLLongPrefix;
       
  4412     aURI.Append( IMEI );
       
  4413     aURI.Append( KFLSuffix );
       
  4414     }
       
  4415 
       
  4416 // ----------------------------------------------------------------------------
       
  4417 // CDRMDbSession::AesEncryptL
       
  4418 // Encrypt data using a given key
       
  4419 // ----------------------------------------------------------------------------
       
  4420 //
       
  4421 void CDRMDbSession::AesEncryptL( const TDesC8& aKey,
       
  4422                                  const TDesC8& aIV,
       
  4423                                  const TBool aAddPadding,
       
  4424                                  TDes8& aData )
       
  4425     {
       
  4426     DRMLOG( _L( "CDRMDbSession::AesEncryptL" ) );
       
  4427 
       
  4428     __UHEAP_MARK;
       
  4429 
       
  4430     CModeCBCEncryptor* cbc( NULL );
       
  4431     TInt lastBlockStart( 0 );
       
  4432     TPtr8 data( NULL, 0, 0 );
       
  4433 
       
  4434     if( aIV.Length() % KDCFKeySize ||
       
  4435         aKey.Length() % KDCFKeySize )
       
  4436         {
       
  4437         User::Leave( KErrArgument );
       
  4438         }
       
  4439 
       
  4440     cbc = CModeCBCEncryptor::NewL( CAESEncryptor::NewLC( aKey ), aIV );
       
  4441     CleanupStack::Pop(); // CAESEncryptor, owned by cbc.
       
  4442     CleanupStack::PushL( cbc );
       
  4443 
       
  4444     lastBlockStart = aData.Length() - ( aData.Length() % KDCFKeySize );
       
  4445     for ( TInt i = 0; i  < lastBlockStart; i+= KDCFKeySize )
       
  4446         {
       
  4447         data.Set( aData.MidTPtr( i, KDCFKeySize ) );
       
  4448 
       
  4449         cbc->Transform( data );
       
  4450         }
       
  4451 
       
  4452     if ( aAddPadding )
       
  4453         {
       
  4454         TInt dataLength = aData.Length();
       
  4455         TUint8 padding( static_cast< TUint8 >
       
  4456             ( lastBlockStart + KDCFKeySize - dataLength ) );
       
  4457 
       
  4458         __ASSERT_DEBUG( lastBlockStart + KDCFKeySize - dataLength <= KDCFKeySize,
       
  4459                         User::Invariant() );
       
  4460 
       
  4461         aData.SetLength( lastBlockStart + KDCFKeySize );
       
  4462 
       
  4463         for ( TInt i = dataLength; i < aData.Length(); ++i )
       
  4464             {
       
  4465             aData[ i ] = padding;
       
  4466             }
       
  4467 
       
  4468         data.Set( aData.MidTPtr( lastBlockStart, KDCFKeySize ) );
       
  4469         cbc->Transform( data );
       
  4470         }
       
  4471 
       
  4472     CleanupStack::PopAndDestroy( cbc );
       
  4473 
       
  4474     __UHEAP_MARKEND;
       
  4475 
       
  4476     DRMLOG( _L( "CDRMDbSession::AesEncryptL ok" ) );
       
  4477     }
       
  4478 
       
  4479 // ----------------------------------------------------------------------------
       
  4480 // CDRMDbSession::AesDecryptL
       
  4481 // Decrypt data using a given key
       
  4482 // ----------------------------------------------------------------------------
       
  4483 //
       
  4484 void CDRMDbSession::AesDecryptL( const TDesC8& aKey,
       
  4485                                  const TDesC8& aIV,
       
  4486                                  const TBool aRemovePadding,
       
  4487                                  TDes8& aData )
       
  4488     {
       
  4489     DRMLOG( _L( "CDRMDbSession::AesDecryptL" ) );
       
  4490 
       
  4491     __UHEAP_MARK;
       
  4492 
       
  4493     CModeCBCDecryptor* cbc( NULL );
       
  4494 
       
  4495     cbc = CModeCBCDecryptor::NewL(
       
  4496         CAESDecryptor::NewLC( aKey ), aIV );
       
  4497 
       
  4498     CleanupStack::Pop(); // CAESDecryptor
       
  4499 
       
  4500     __ASSERT_DEBUG( ( aData.Length() >= 0 ) &&
       
  4501                     ( aData.Length() % KDCFKeySize == 0 ),
       
  4502                     User::Invariant() );
       
  4503 
       
  4504     for ( TInt count = 0; count < aData.Length(); count += KDCFKeySize )
       
  4505         {
       
  4506         TPtr8 d( aData.MidTPtr( count, KDCFKeySize ) );
       
  4507 
       
  4508         cbc->Transform( d );
       
  4509         }
       
  4510 
       
  4511     delete cbc; cbc = NULL;
       
  4512 
       
  4513     if ( aRemovePadding )
       
  4514         {
       
  4515         TInt count( aData.Length() );
       
  4516         TUint8 c( aData[ count - 1 ] );
       
  4517 
       
  4518         if ( c > KDCFKeySize )
       
  4519             {
       
  4520             User::Leave( KErrCorrupt );
       
  4521             }
       
  4522 
       
  4523         aData.SetLength( count - c );
       
  4524         }
       
  4525 
       
  4526     __UHEAP_MARKEND;
       
  4527 
       
  4528     DRMLOG( _L( "CDRMDbSession::AesDecryptL ok" ) );
       
  4529     }
       
  4530 
       
  4531 // ----------------------------------------------------------------------------
       
  4532 // CDRMDbSession::
       
  4533 //
       
  4534 // ----------------------------------------------------------------------------
       
  4535 //
       
  4536 void CDRMDbSession::GenerateIVL( TDes8& aIV )
       
  4537     {
       
  4538     DRMLOG( _L( "CDRMDbSession::GenerateIVL" ) );
       
  4539     __UHEAP_MARK;
       
  4540 
       
  4541     __ASSERT_DEBUG( aIV.MaxSize() >= KDCFKeySize, User::Invariant() );
       
  4542     MDrmKeyStorage* storage = DrmKeyStorageNewL();
       
  4543     TCleanupItem storageCleanup( DeleteObject, storage );
       
  4544     CleanupStack::PushL(storageCleanup);
       
  4545 
       
  4546     storage->RandomDataGetL(aIV,KDCFKeySize);
       
  4547     CleanupStack::PopAndDestroy( storage );
       
  4548 
       
  4549     DRMLOG(_L("random aIV:"));
       
  4550     DRMLOGHEX(aIV);
       
  4551 
       
  4552 
       
  4553     __UHEAP_MARKEND;
       
  4554     DRMLOG( _L( "CDRMDbSession::GenerateIVL ok" ) );
       
  4555     }
       
  4556 
       
  4557 // ----------------------------------------------------------------------------
       
  4558 // CDRMDbSession::
       
  4559 //
       
  4560 // ----------------------------------------------------------------------------
       
  4561 //
       
  4562 void CDRMDbSession::AsyncOperationDone()
       
  4563     {
       
  4564     DRMLOG( _L( "CDRMDbSession::AsyncOperationDone" ) );
       
  4565     // All done.
       
  4566     delete iPendingRequest;
       
  4567     iPendingRequest = NULL;
       
  4568     }
       
  4569 
       
  4570 // ----------------------------------------------------------------------------
       
  4571 // CDRMDbSession::
       
  4572 //
       
  4573 // ----------------------------------------------------------------------------
       
  4574 //
       
  4575 void CDRMDbSession::AsyncOperationDone( TFileName* aFileName )
       
  4576     {
       
  4577     DRMLOG( _L( "CDRMDbSession::AsyncOperationDone" ) );
       
  4578     // All done.
       
  4579     delete iPendingRequest;
       
  4580     iPendingRequest = NULL;
       
  4581 
       
  4582     iFileName = aFileName;
       
  4583     }
       
  4584 
       
  4585 
       
  4586 // ----------------------------------------------------------------------------
       
  4587 // CDRMDbSession::SetAuthenticationSeedL
       
  4588 // Sets the authentication seed for a content ID. Requires that the REK and KEK
       
  4589 // have been set during a previous AddRecord operation
       
  4590 // ----------------------------------------------------------------------------
       
  4591 //
       
  4592 void CDRMDbSession::SetAuthenticationSeedL( const RMessage2& aMessage )
       
  4593     {
       
  4594     DRMLOG(_L("CDRMDbSession::SetAuthenticationSeedL"));
       
  4595 
       
  4596     __UHEAP_MARK;
       
  4597     SanitizeL( aMessage.GetDesLength(0));
       
  4598     SanitizeL( aMessage.GetDesLength(1));
       
  4599 
       
  4600     HBufC8* cid = HBufC8::NewLC(IPCGETDESLEN0);
       
  4601     HBufC8* wrappedSeed = HBufC8::NewLC(IPCGETDESLEN1);
       
  4602     HBufC8* seed = NULL;
       
  4603 
       
  4604     if (iRek.Length() == 0)
       
  4605         {
       
  4606         User::Leave(KErrNotReady);
       
  4607         }
       
  4608 
       
  4609     TPtr8 tmp(cid->Des());
       
  4610     IPCREAD0L(tmp );
       
  4611     TPtr8 tmp2(wrappedSeed->Des());
       
  4612     IPCREAD1L(tmp2);
       
  4613 
       
  4614     seed = OmaCrypto::AesUnwrapL(iRek, *wrappedSeed);
       
  4615     CleanupStack::PushL(seed);
       
  4616     DRMDB.SetAuthenticationSeedL(*cid, *seed);
       
  4617     CleanupStack::PopAndDestroy(3); // seed, wrappedSeed, cid
       
  4618     __UHEAP_MARKEND;
       
  4619     aMessage.Complete(KErrNone);
       
  4620     }
       
  4621 
       
  4622 // ----------------------------------------------------------------------------
       
  4623 // CDRMDbSession::GetAuthenticationSeedL
       
  4624 // Returns the authentication seed for a content ID
       
  4625 // ----------------------------------------------------------------------------
       
  4626 //
       
  4627 void CDRMDbSession::GetAuthenticationSeedL( const RMessage2& aMessage )
       
  4628     {
       
  4629     DRMLOG(_L("CDRMDbSession::GetAuthenticationSeedL"));
       
  4630 
       
  4631     __UHEAP_MARK;
       
  4632     HBufC8* cid = NULL;
       
  4633     HBufC8* seed = NULL;
       
  4634 
       
  4635     SanitizeL( aMessage.GetDesLength(0));
       
  4636     cid = HBufC8::NewLC(IPCGETDESLEN0);
       
  4637 
       
  4638     TPtr8 tmp(cid->Des());
       
  4639     IPCREAD0L(tmp);
       
  4640     User::LeaveIfError(VerifyCredentials(cid, NULL, EUnknown));
       
  4641     seed = DRMDB.GetAuthenticationSeedL(*cid);
       
  4642     CleanupStack::PushL(seed);
       
  4643 
       
  4644     if( seed->Length() > aMessage.GetDesMaxLength(1) )
       
  4645         {
       
  4646         User::Leave(KErrArgument);
       
  4647         }
       
  4648 
       
  4649     IPCWRITE1L(*seed);
       
  4650     CleanupStack::PopAndDestroy(2); // seed, cid
       
  4651     __UHEAP_MARKEND;
       
  4652     aMessage.Complete(KErrNone);
       
  4653     }
       
  4654 
       
  4655 // ----------------------------------------------------------------------------
       
  4656 // CDRMDbSession::VerifyMacL
       
  4657 // Integrity protection for protecets ROs
       
  4658 // ----------------------------------------------------------------------------
       
  4659 //
       
  4660 void CDRMDbSession::VerifyMacL( const RMessage2& aMessage )
       
  4661     {
       
  4662     DRMLOG(_L("CDRMDbSession::VerifyMacL"));
       
  4663 
       
  4664     if( !iMac.Length() )
       
  4665         {
       
  4666         User::Leave(KErrNotReady);
       
  4667         }
       
  4668 
       
  4669     __UHEAP_MARK;
       
  4670 
       
  4671     CHMAC* hMac = NULL;
       
  4672     CSHA1* sha = NULL;
       
  4673     TPtrC8 hmac_value( KNullDesC8 );
       
  4674     TPtrC8 sha1_value( KNullDesC8 );
       
  4675     HBufC8* signedInfo = NULL;
       
  4676     HBufC8* macValue = NULL;
       
  4677     TInt ret = KErrNone;
       
  4678 
       
  4679     signedInfo = HBufC8::NewLC(IPCGETDESLEN0);
       
  4680     TPtr8 signedInfoPtr(signedInfo->Des());
       
  4681     macValue = HBufC8::NewLC(IPCGETDESLEN1);
       
  4682     TPtr8 macValuePtr(macValue->Des());
       
  4683 
       
  4684     IPCREAD0L(signedInfoPtr);
       
  4685     IPCREAD1L(macValuePtr);
       
  4686 
       
  4687     DRMLOG(_L("Signed info:"));
       
  4688     DRMLOGHEX(signedInfoPtr);
       
  4689     DRMLOG(_L("MAC value:"));
       
  4690     DRMLOGHEX(macValuePtr);
       
  4691 
       
  4692     sha = CSHA1::NewL();
       
  4693     CleanupStack::PushL( sha );
       
  4694     hMac = CHMAC::NewL( iMac, sha );
       
  4695     CleanupStack::Pop( sha ); // sha is now owned by hMac
       
  4696     CleanupStack::PushL( hMac );
       
  4697     hMac->Update( signedInfoPtr );
       
  4698     hmac_value.Set( hMac->Final() );
       
  4699 
       
  4700     DRMLOG(_L("Calculated MAC value:"));
       
  4701     DRMLOGHEX(hmac_value);
       
  4702     if ( hmac_value.Compare( macValuePtr ) != 0 )
       
  4703         {
       
  4704         // MAC validation failed
       
  4705         ret = KErrRightsServerMacFailed;
       
  4706         }
       
  4707 
       
  4708     CleanupStack::PopAndDestroy(3, signedInfo); // hMac, macValue, signedInfo
       
  4709     __UHEAP_MARKEND;
       
  4710     aMessage.Complete(ret);
       
  4711     }
       
  4712 
       
  4713 // ----------------------------------------------------------------------------
       
  4714 // CDRMDbSession::GetSupportedIndividualsL
       
  4715 // ----------------------------------------------------------------------------
       
  4716 //
       
  4717 void CDRMDbSession::GetSupportedIndividualsL( const RMessage2& aMessage )
       
  4718     {
       
  4719     DRMLOG( _L( "CDRMDbSession::GetSupportedIndividualsL" ) );
       
  4720     TPckgBuf< TInt > size( 0 );
       
  4721     TInt stringSize = 0;
       
  4722     TInt offset = 0;
       
  4723     TUint8* ptr = 0;
       
  4724 
       
  4725     // Cleanup.
       
  4726     if ( iPreparedData )
       
  4727         {
       
  4728         delete iPreparedData;
       
  4729         iPreparedData = NULL;
       
  4730         }
       
  4731 
       
  4732     for ( TInt i = 0; i < IMSI.Count(); i++ )
       
  4733         {
       
  4734         stringSize += sizeof(TInt);
       
  4735         stringSize += IMSI[i]->Size();
       
  4736         }
       
  4737 
       
  4738 
       
  4739     // If it's empty, just return right away
       
  4740     if( !stringSize )
       
  4741         {
       
  4742         IPCWRITE0L( size );
       
  4743         aMessage.Complete(KErrNone);
       
  4744         return;
       
  4745         }
       
  4746 
       
  4747     // Otherwise create a buffer and fill it:
       
  4748     iPreparedData = HBufC8::NewMaxL( stringSize );
       
  4749     ptr = const_cast<TUint8*>( iPreparedData->Ptr() );
       
  4750 
       
  4751     size() = stringSize;
       
  4752 
       
  4753     for(  TInt i = 0; i < IMSI.Count(); i++ )
       
  4754         {
       
  4755         // Write the size:
       
  4756         stringSize = IMSI[i]->Size();
       
  4757         Mem::Copy(ptr+offset, &stringSize, sizeof(TInt));
       
  4758         offset += sizeof(TInt);
       
  4759 
       
  4760         // Write the data:
       
  4761         Mem::Copy(ptr+offset, IMSI[i]->Ptr(), IMSI[i]->Size());
       
  4762         offset += IMSI[i]->Size();
       
  4763         }
       
  4764     IPCWRITE0L( size );
       
  4765 
       
  4766     aMessage.Complete( KErrNone );
       
  4767     }
       
  4768 
       
  4769 // ----------------------------------------------------------------------------
       
  4770 // CDRMDbSession::StopWatchingL
       
  4771 // ----------------------------------------------------------------------------
       
  4772 //
       
  4773 void CDRMDbSession::StopWatchingL( const RMessage2& aMessage )
       
  4774     {
       
  4775     _LIT_SECURITY_POLICY_S0( sidCheck, KTrustedShutdownClient );
       
  4776     if ( sidCheck.CheckPolicy( aMessage ) )
       
  4777         {
       
  4778         SERVER->StopWatchingL();
       
  4779         }
       
  4780     aMessage.Complete( KErrNone );
       
  4781     }
       
  4782 
       
  4783 // ----------------------------------------------------------------------------
       
  4784 // CDRMDbSession::DeleteAllowedL
       
  4785 // ----------------------------------------------------------------------------
       
  4786 //
       
  4787 TBool CDRMDbSession::DeleteAllowedL( const TDesC8& aContentId )
       
  4788     {
       
  4789     TBuf8< KMaxOmaV1CIDLength > URI;
       
  4790 
       
  4791     // Get the FL uri
       
  4792     GetFlURI( URI );
       
  4793 
       
  4794     if( aContentId.Compare( URI ) &&
       
  4795         aContentId.Compare( KDCMUri ) &&
       
  4796         aContentId.Compare( KLDFUri ) )
       
  4797         {
       
  4798         return ETrue;
       
  4799         }
       
  4800     return EFalse;
       
  4801     }
       
  4802 
       
  4803 // ----------------------------------------------------------------------------
       
  4804 // CDRMDbSession::GetRandomDataL
       
  4805 // ----------------------------------------------------------------------------
       
  4806 //
       
  4807 void CDRMDbSession::GetRandomDataL( const RMessage2& aMessage )
       
  4808     {
       
  4809     DRMLOG(_L("CDRMDbSession::GetRandomDataL"));
       
  4810 
       
  4811     HBufC8* data = NULL;
       
  4812     SanitizeL( aMessage.GetDesMaxLength(0) );
       
  4813     SanitizeL( aMessage.GetDesLength(0));
       
  4814 
       
  4815     data = HBufC8::NewMaxLC(IPCGETDESLEN0);
       
  4816     TPtr8 ptr(data->Des());
       
  4817 
       
  4818     MDrmKeyStorage* storage = DrmKeyStorageNewL();
       
  4819     TCleanupItem storageCleanup( DeleteObject, storage );
       
  4820     CleanupStack::PushL(storageCleanup);
       
  4821     storage->RandomDataGetL(ptr,ptr.Size());
       
  4822     IPCWRITE0L(*data);
       
  4823 
       
  4824     CleanupStack::PopAndDestroy(2, data);
       
  4825     aMessage.Complete( KErrNone );
       
  4826     }
       
  4827 
       
  4828 // -----------------------------------------------------------------------------
       
  4829 // CDRMDbSession::GetMeteringDataL
       
  4830 // -----------------------------------------------------------------------------
       
  4831 //
       
  4832 void CDRMDbSession::GetMeteringDataL( const RMessage2& aMessage )
       
  4833     {
       
  4834 #ifndef RD_DRM_METERING
       
  4835     aMessage.Complete ( KErrNotSupported );
       
  4836 #else
       
  4837     HBufC8* riId = NULL;
       
  4838     HBufC8* meteringData = NULL;
       
  4839     CDRMPointerArray<CDrmMeteringDbData>* meteringArray =
       
  4840         CDRMPointerArray<CDrmMeteringDbData>::NewLC();
       
  4841     meteringArray->SetAutoCleanup( ETrue );
       
  4842 
       
  4843     TInt size = 0;
       
  4844     TPtr8 data( NULL, 0 );
       
  4845     TPckg<TInt> package( size );
       
  4846 
       
  4847     SanitizeL( aMessage.GetDesLength(0));
       
  4848     // Empty old data
       
  4849     delete iPreparedData;
       
  4850     iPreparedData = NULL;
       
  4851 
       
  4852     riId = HBufC8::NewLC( User::LeaveIfError( IPCGETDESLEN1 ) );
       
  4853     data.Set( riId->Des() );
       
  4854     IPCREAD1L( data );
       
  4855 
       
  4856     if ( METERINGDB.GetL( *riId, *meteringArray ) )
       
  4857         {
       
  4858         meteringData = CreateMeteringDataL( meteringArray );
       
  4859         CleanupStack::PushL( meteringData );
       
  4860         }
       
  4861     else
       
  4862         {
       
  4863         _LIT8( KEmptyMetering, "<rawMeteringReportData>\r\n</rawMeteringReportData>");
       
  4864         meteringData = KEmptyMetering().AllocLC();
       
  4865         }
       
  4866     DRMLOGHEX( *meteringData );
       
  4867     size = meteringData->Size();
       
  4868     iPreparedData = meteringData;
       
  4869     CleanupStack::Pop( meteringData );
       
  4870 
       
  4871     IPCWRITE0L( package );
       
  4872     CleanupStack::PopAndDestroy( 2 ); // riId, meteringArray
       
  4873     if ( !iPreparedData )
       
  4874         {
       
  4875         aMessage.Complete( KErrNotFound );
       
  4876         return;
       
  4877         }
       
  4878     aMessage.Complete( KErrNone );
       
  4879 #endif
       
  4880     }
       
  4881 
       
  4882 // -----------------------------------------------------------------------------
       
  4883 // CDRMDbSession::DeleteMeteringDataL
       
  4884 // -----------------------------------------------------------------------------
       
  4885 //
       
  4886 void CDRMDbSession::DeleteMeteringDataL( const RMessage2& aMessage )
       
  4887     {
       
  4888 #ifndef RD_DRM_METERING
       
  4889     aMessage.Complete ( KErrNotSupported );
       
  4890 #else
       
  4891 // Metering supported
       
  4892     HBufC8* riId = NULL;
       
  4893     TPtr8 data( NULL, 0 );
       
  4894     TBool meteringDataDeleted;
       
  4895 
       
  4896     riId = HBufC8::NewLC( User::LeaveIfError( IPCGETDESLEN0 ) );
       
  4897     data.Set( riId->Des() );
       
  4898     IPCREAD0L( data );
       
  4899     meteringDataDeleted = METERINGDB.DeleteL( *riId );
       
  4900 
       
  4901         if( meteringDataDeleted )
       
  4902             {
       
  4903             DRMLOG( _L("CDRMDbSession::DeleteMeteringDataL -> some records were destroyed") );
       
  4904             }
       
  4905     // Do we have to do something else?
       
  4906     CleanupStack::PopAndDestroy( riId );
       
  4907     aMessage.Complete( KErrNone );
       
  4908 #endif
       
  4909     }
       
  4910 // -----------------------------------------------------------------------------
       
  4911 // CDRMDbSession::ConnectRoapClient()
       
  4912 // -----------------------------------------------------------------------------
       
  4913 //
       
  4914 TInt CDRMDbSession::ConnectRoapClient()
       
  4915     {
       
  4916     if( iRoapClientConnected )
       
  4917         {
       
  4918         return KErrNone;
       
  4919         }
       
  4920     TInt err( iRoapClient.Connect() );
       
  4921     if ( !err )
       
  4922         {
       
  4923         iRoapClientConnected = ETrue;
       
  4924         }
       
  4925     return err;
       
  4926     }
       
  4927 
       
  4928 //  End of File