omadrm/drmengine/dm/src/DRMMessageParser.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2004 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 implements the BbB-functionality.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include <e32base.h>
       
    22 #include <s32file.h>
       
    23 #include <s32mem.h>
       
    24 #include <caf/caftypes.h>
       
    25 #include <wspdecoder.h>
       
    26 #include <wspencoder.h>
       
    27 
       
    28 #ifdef RD_MULTIPLE_DRIVE
       
    29 #include <DriveInfo.h>
       
    30 #endif
       
    31 
       
    32 #include "DrmRights.h"
       
    33 #include "Oma1DcfCreator.h"
       
    34 #include "b64.h"
       
    35 #include "DRMMessageParser.h"
       
    36 #include "DRMRightsParser.h"
       
    37 #include "DRMRightsClient.h"
       
    38 #include "DrmKeyStorage.h"
       
    39 
       
    40 
       
    41 // EXTERNAL DATA STRUCTURES
       
    42 // EXTERNAL FUNCTION PROTOTYPES  
       
    43 // CONSTANTS
       
    44 // MACROS
       
    45 // LOCAL CONSTANTS AND MACROS
       
    46 LOCAL_C const TInt KDefaultInputBufferSize = 2048;
       
    47 LOCAL_C const TInt KDRMMessageMalformed = KErrGeneral;
       
    48 
       
    49 _LIT8( KCIDString, "cid:" );
       
    50 LOCAL_C const TInt KCIDStringLength = 4;
       
    51 
       
    52 _LIT8( KFLPrefix, "flk:");
       
    53 LOCAL_C const TInt KFLKPrefixLength = 4;
       
    54 
       
    55 _LIT8( KFLSuffix, "@localhost");
       
    56 LOCAL_C const TUint8 KCDContentIDLength = 25; // 4 + 11 + 10
       
    57 LOCAL_C const TUint8 KCDPlainIDLength = 11; 
       
    58 
       
    59 LOCAL_C const TInt KInputBufferSize = 2048;
       
    60 LOCAL_C const TInt KBoundaryMarkLength = 2;
       
    61 
       
    62 LOCAL_C const TUint KInitialDCFBufferSize = 4096;
       
    63 
       
    64 #ifdef RD_MULTIPLE_DRIVE
       
    65 _LIT( KTempPath, "%c:\\system\\temp\\" );
       
    66 #else
       
    67 _LIT( KTempPath, "c:\\system\\temp\\" );
       
    68 #endif
       
    69 
       
    70 _LIT8( KColon, ":" );
       
    71 _LIT8( KSemiColon, ";" );
       
    72 _LIT8( KNewLine, "\n" );
       
    73 _LIT8( KEndLine, "\r\n" );
       
    74 LOCAL_C const TUint8 KEndLineLength = 2;
       
    75 
       
    76 _LIT8( KBoundaryMark, "--" );
       
    77 _LIT8( KContentType, "Content-Type" );
       
    78 _LIT8( KContentTransferEncoding, "Content-Transfer-Encoding" );
       
    79 _LIT8( KEncodingBase64, "base64" );
       
    80 _LIT8( KEncoding7bit, "7bit" );
       
    81 _LIT8( KEncoding8bit, "8bit" );
       
    82 _LIT8( KEncodingBinary, "binary" );
       
    83 _LIT8( KDRMXMLRightsType, "application/vnd.oma.drm.rights+xml");
       
    84 _LIT8( KDRMWBXMLRightsType, "application/vnd.oma.drm.rights+wbxml" );
       
    85 _LIT8( KDRMContentType, "application/vnd.oma.drm.content" );
       
    86 _LIT8( KRightsIssuer, "Rights-Issuer" );
       
    87 
       
    88 _LIT8( KRightsStartTag, "<o-ex:rights");
       
    89 
       
    90 _LIT8( KROPart1, "Content-Type: application/vnd.oma.drm.rights+xml\r\n\
       
    91 Content-Transfer-Encoding: binary\r\n\r\n\
       
    92 <o-ex:rights xmlns:o-ex=\"http://odrl.net/1.1/ODRL-EX\" \
       
    93 xmlns:o-dd=\"http://odrl.net/1.1/ODRL-DD\" \
       
    94 xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#/\">\
       
    95 <o-ex:context><o-dd:version>1.0</o-dd:version></o-ex:context>\
       
    96 <o-ex:agreement><o-ex:asset><o-ex:context>\
       
    97 <o-dd:uid>");
       
    98 
       
    99 _LIT8( KROPart2, "</o-dd:uid></o-ex:context></o-ex:asset><o-ex:permission>\
       
   100 <o-dd:display/><o-dd:play/><o-dd:execute/><o-dd:print/>\
       
   101 </o-ex:permission></o-ex:agreement></o-ex:rights>");
       
   102 
       
   103 const TInt KFLROSize = sizeof(KROPart1) + sizeof(KROPart2);
       
   104 
       
   105 // MODULE DATA STRUCTURES
       
   106 struct TDeleteFileData
       
   107     {
       
   108     RFs aFs;
       
   109     TFileName aName;
       
   110     };
       
   111     
       
   112 // LOCAL FUNCTION PROTOTYPES
       
   113 LOCAL_C void DoResetAndDestroy( TAny* aPtr );
       
   114 LOCAL_C void DoResetAndDestroy2( TAny* aPtr );
       
   115 LOCAL_C void DoDeleteFile( TAny* aPtr );
       
   116 LOCAL_C void ConvertPermissionL( CDRMRights*& aRights,
       
   117                                  CDRMPermission& aPermission,
       
   118                                  const TDesC8& aURI );
       
   119 // FORWARD DECLARATIONS
       
   120 
       
   121 // ============================= LOCAL FUNCTIONS ===============================
       
   122 // -----------------------------------------------------------------------------
       
   123 // DoResetAndDestroy
       
   124 // Does ResetAndDestroy() to given RPointerArray< CDRMRights >
       
   125 // -----------------------------------------------------------------------------
       
   126 void DoResetAndDestroy( TAny* aPtr )
       
   127     {
       
   128     __ASSERT_DEBUG( aPtr, User::Invariant() );
       
   129     
       
   130     reinterpret_cast< RPointerArray< CDRMRights >* >( aPtr )->ResetAndDestroy();
       
   131     }
       
   132 
       
   133 void DoResetAndDestroy2( TAny* aPtr )
       
   134     {
       
   135     __ASSERT_DEBUG( aPtr, User::Invariant() );
       
   136     
       
   137     reinterpret_cast< RPointerArray< CDRMPermission >* >( aPtr )->ResetAndDestroy();
       
   138     }
       
   139 // -----------------------------------------------------------------------------
       
   140 // DoDeleteFile
       
   141 // Delete the file presented by TDeleteFileData pointer.
       
   142 // -----------------------------------------------------------------------------
       
   143 void DoDeleteFile( TAny* aPtr )
       
   144     {
       
   145     __ASSERT_DEBUG( aPtr, User::Invariant() );
       
   146     TDeleteFileData* data = reinterpret_cast< TDeleteFileData* >( aPtr );
       
   147     data->aFs.Delete( data->aName );
       
   148     }
       
   149 
       
   150 void ConvertPermissionL( CDRMRights*& aRights,
       
   151                          CDRMPermission& aPermission,
       
   152                          const TDesC8& aURI )
       
   153     {
       
   154     CDRMAsset* asset( NULL );
       
   155     CDRMRights* rights( NULL );
       
   156     
       
   157     aRights = NULL;
       
   158     
       
   159     rights = CDRMRights::NewL();
       
   160     CleanupStack::PushL( rights );
       
   161     
       
   162     asset = CDRMAsset::NewL();
       
   163     CleanupStack::PushL( asset );
       
   164     
       
   165     asset->iUid = aURI.AllocL();
       
   166     
       
   167     if ( aPermission.iParentUID )
       
   168         {
       
   169         asset->iParentRights = aPermission.iParentUID->AllocL();
       
   170         }
       
   171     
       
   172     rights->SetPermissionL( aPermission );
       
   173     rights->SetAssetL( *asset );
       
   174     
       
   175     CleanupStack::PopAndDestroy(); // asset
       
   176     CleanupStack::Pop(), // rights
       
   177     
       
   178     aRights = rights;
       
   179     }
       
   180 
       
   181 // ============================ MEMBER FUNCTIONS ===============================
       
   182 // -----------------------------------------------------------------------------
       
   183 // CDRMMessageParser::NewL
       
   184 // Two-phased constructor.
       
   185 // -----------------------------------------------------------------------------
       
   186 //
       
   187 EXPORT_C CDRMMessageParser* CDRMMessageParser::NewL( void )
       
   188     {
       
   189     CDRMMessageParser* self = new( ELeave ) CDRMMessageParser();
       
   190     
       
   191     CleanupStack::PushL( self );
       
   192     self->ConstructL();
       
   193     CleanupStack::Pop();
       
   194     
       
   195     return self;
       
   196     }
       
   197 
       
   198 // -----------------------------------------------------------------------------
       
   199 // CDRMMessageParser::CDRMMessageParser
       
   200 // Constructor.
       
   201 // -----------------------------------------------------------------------------
       
   202 //
       
   203 CDRMMessageParser::CDRMMessageParser() :
       
   204     iDcfCreator( NULL ),
       
   205     iBoundary( NULL ),
       
   206     iContentType( NULL ),
       
   207     iState( ESearchingBoundary ),
       
   208     iInputBuffer( NULL, 0, 0 )
       
   209     {
       
   210     iDCFHeaderSize[ 0 ] = KMaxTUint32;
       
   211     iDCFHeaderSize[ 1 ] = KMaxTUint32;
       
   212     }
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // Destructor.
       
   216 // -----------------------------------------------------------------------------
       
   217 //
       
   218 EXPORT_C CDRMMessageParser::~CDRMMessageParser()
       
   219     {
       
   220     TInt error = KErrNone;
       
   221     TRAP( error, FinalizeMessageParserL() );
       
   222     
       
   223     Reset();
       
   224     
       
   225     User::Free( const_cast< TUint8* >( iInputBuffer.Ptr() ) );
       
   226     }
       
   227 
       
   228 // -----------------------------------------------------------------------------
       
   229 // CDRMMessageParser::
       
   230 // 
       
   231 // -----------------------------------------------------------------------------
       
   232 //
       
   233 EXPORT_C void CDRMMessageParser::InitializeMessageParserL( RWriteStream& aStream )
       
   234     {
       
   235     Reset();
       
   236     
       
   237     iDcfCreator = COma1DcfCreator::NewL();
       
   238     
       
   239     iOutputStream = aStream;
       
   240     }
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 // CDRMMessageParser::ProcessDataL
       
   244 // Choose which operation is required.
       
   245 // -----------------------------------------------------------------------------
       
   246 EXPORT_C void CDRMMessageParser::ProcessMessageDataL( const TDesC8& aMessageData )
       
   247     {
       
   248     /*
       
   249     * What happens here is:
       
   250     *   - a boundary string is located and extracted
       
   251     *   - MIME header is read, and based on content-type field the internal
       
   252     *     state is set to either EReadingRightsPart or EReadingContentPart.
       
   253     *   - after processing the MIME part, internal state is updated again to 
       
   254     *     EReadingHeaderPart if there are several MIME parts in the DRM 
       
   255     *     message.
       
   256     *   - data is consumed from iInputData in each phase.
       
   257     *   - after everything is done, internal state is set to EAllDone.
       
   258     */
       
   259     if ( iState & EBroken )
       
   260         {
       
   261         User::Leave( KErrNotReady );
       
   262         }
       
   263     
       
   264     if ( iState & EAllDone )
       
   265         {
       
   266         return;
       
   267         }
       
   268     
       
   269     iInputData.Set( aMessageData );
       
   270     
       
   271     while( iInputData.Length() )
       
   272         {
       
   273         if ( iState & EReadingHeaderPart )
       
   274             {
       
   275             ReadHeaderL();
       
   276             }
       
   277         else
       
   278             {
       
   279             if ( iState & EReadingContentPart )
       
   280                 {
       
   281                 HandleContentDataL();
       
   282                 }
       
   283             else
       
   284                 {
       
   285                 if ( iState & EReadingRightsPart )
       
   286                     {
       
   287                     HandleRightsDataL();
       
   288                     }
       
   289                 else
       
   290                     {
       
   291                     FindBoundaryL();
       
   292                     }
       
   293                 }
       
   294             }
       
   295         }
       
   296     }
       
   297 
       
   298 // -----------------------------------------------------------------------------
       
   299 // CDRMMessageParser::FinalizeL
       
   300 // Finalize the message parser.
       
   301 // -----------------------------------------------------------------------------
       
   302 EXPORT_C void CDRMMessageParser::FinalizeMessageParserL()
       
   303     {
       
   304     TInt error( KErrNone );
       
   305     
       
   306     if ( iState & EEncryptStreamOk )
       
   307         {
       
   308         if ( iInputBuffer.Length() )
       
   309             {
       
   310             // Message is not parsed fully ==> error.
       
   311             // Try to delete the RO if it is possible.
       
   312             DeletePermission();
       
   313             error = KDRMMessageMalformed;
       
   314             }
       
   315             
       
   316         ClearBit( EEncryptStreamOk );
       
   317         iDcfCreator->EncryptFinalizeL();
       
   318         
       
   319         iOutputStream.CommitL();
       
   320         }
       
   321 
       
   322     Reset();
       
   323     
       
   324     User::LeaveIfError( error );
       
   325     }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // CDRMMessageParser::ConstructL
       
   329 // Symbian 2nd phase constructor can leave.
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CDRMMessageParser::ConstructL()
       
   333     {
       
   334     // Make some extra room for crazy b64decode().
       
   335     iInputBuffer.Set( reinterpret_cast< TUint8* >( 
       
   336                         User::AllocL( KInputBufferSize + 2 ) ), 
       
   337                       0, 
       
   338                       KInputBufferSize );
       
   339     }
       
   340 
       
   341 // -----------------------------------------------------------------------------
       
   342 // CDRMMessageParser::HandleContentDataL
       
   343 // Process the content data:
       
   344 // - base64 decoding
       
   345 // - boundary checks
       
   346 // - forward the processed data to ProcessContentDataL
       
   347 // -----------------------------------------------------------------------------
       
   348 //
       
   349 void CDRMMessageParser::HandleContentDataL()
       
   350     {
       
   351    TPtrC8 res( NULL, 0 );
       
   352     TBool cont( ETrue );
       
   353     TInt remainder( 0 );
       
   354     
       
   355     // Loop until 
       
   356     // - PrepareContentDataL leaves
       
   357     // - boundary end marker is found
       
   358     // - iInputBuffer is not updated anymore.
       
   359     for ( PrepareContentDataL(); 
       
   360           iInputBuffer.Length() && 
       
   361               ( remainder != iInputBuffer.Length() ) && 
       
   362               cont;
       
   363           PrepareContentDataL() )
       
   364         {
       
   365         TInt pos = iInputBuffer.Find( *iBoundary );
       
   366         
       
   367         if ( pos >= 0 )
       
   368             {
       
   369             if ( pos < KBoundaryMarkLength + 1 ) 
       
   370                 {
       
   371                 SetBrokenStateL( KDRMMessageMalformed );
       
   372                 }
       
   373             
       
   374             res.Set( iInputBuffer.Left( pos - KBoundaryMarkLength ) );
       
   375             
       
   376             StripEndLineL( res );
       
   377             
       
   378             cont = EFalse;
       
   379             }
       
   380         else
       
   381             {
       
   382             // All the data cannot be processed immediately, because
       
   383             // there may be only a part of boundary string in this buffer
       
   384             // and the rest is got from the next input descriptor.
       
   385             remainder = iBoundary->Length() + KBoundaryMarkLength + 1;
       
   386             
       
   387             if ( iInputBuffer.Length() <= remainder )
       
   388                 {
       
   389                 return;
       
   390                 }
       
   391             
       
   392             res.Set( iInputBuffer.Left( iInputBuffer.Length() - 
       
   393                                         remainder ) );
       
   394             }
       
   395         
       
   396         if ( iState & EBase64 )
       
   397             {
       
   398             iUsedFromInput = HandleBase64DataL( res );
       
   399             }
       
   400         
       
   401         else
       
   402             {
       
   403             iUsedFromInput = res.Length();
       
   404             }
       
   405         
       
   406         ProcessContentDataL( res );
       
   407         
       
   408         CompressInputBuffer();
       
   409 
       
   410         remainder = iInputBuffer.Length(); 
       
   411         }
       
   412     
       
   413     if ( !cont )
       
   414         {
       
   415         // Discard all the remaining data.
       
   416         ClearBit( EReadingContentPart );
       
   417         SetBit( EAllDone );
       
   418         iInputBuffer.SetLength( 0 );
       
   419         iInputData.Set( NULL, 0 );
       
   420         }
       
   421     }
       
   422 
       
   423 // -----------------------------------------------------------------------------
       
   424 // CDRMMessageParser::HandleRightsDataL
       
   425 // - check if the boundary is reached
       
   426 // - check if the whole rights part is read, and allocate memory && copy the RO
       
   427 //   if so
       
   428 // - save the rights object
       
   429 // -----------------------------------------------------------------------------
       
   430 //
       
   431 void CDRMMessageParser::HandleRightsDataL()
       
   432     {
       
   433     TPtrC8 res( NULL, 0 );
       
   434     
       
   435     do
       
   436         {
       
   437         res.Set( GetLineL() );
       
   438         
       
   439         TInt pos = res.Find( *iBoundary );
       
   440         
       
   441         if ( pos >= KBoundaryMarkLength )
       
   442             {
       
   443             if ( res.Left( KBoundaryMarkLength ) == KBoundaryMark )
       
   444                 {
       
   445                 // Allow empty RO here. If it is not allowed by 
       
   446                 // HandleRightsMessagePart(), an error is thrown.
       
   447                 TBool last = EFalse;
       
   448                 
       
   449                 // Returns always true.
       
   450                 IsBoundary( res, last );
       
   451                 
       
   452                 if ( last )
       
   453                     {
       
   454                     TInt error( KErrNone );
       
   455                     RPointerArray< CDRMRights > rights;
       
   456                     TPtrC8 ptr( iInputBuffer.Ptr(),         
       
   457                                 pos - KBoundaryMarkLength );
       
   458                     
       
   459                     error = ProcessRightsObject(ptr, rights);
       
   460                     rights.ResetAndDestroy();
       
   461                     
       
   462                     if ( !error )
       
   463                         {
       
   464                         SetBit( EAllDone );
       
   465                         }
       
   466                     else
       
   467                         {
       
   468                         SetBrokenStateL( error );
       
   469                         }
       
   470                     }
       
   471                 else
       
   472                     {
       
   473                     // Save the RO since the CID needs to be either changed 
       
   474                     // or created.
       
   475                     iRightsData = iInputBuffer.Left( iUsedFromInput - 
       
   476                                                      res.Length() ).AllocL();
       
   477                     }
       
   478                 
       
   479                 CompressInputBuffer();
       
   480                 
       
   481                 ClearBit( EReadingRightsPart );
       
   482                 ClearBit( EGotContentType );
       
   483                 ClearBit( EGotContentEncoding );
       
   484 
       
   485                 SetBit( EGotRightsPart );
       
   486                 SetBit( EReadingHeaderPart );
       
   487                 
       
   488                 res.Set( NULL, 0 );
       
   489 #ifndef __DRM_FULL
       
   490                 User::Leave(KErrNotSupported);
       
   491 #endif                
       
   492                 }
       
   493             else
       
   494                 {
       
   495                 SetBrokenStateL( KDRMMessageMalformed );
       
   496                 }
       
   497             }
       
   498         else
       
   499             {
       
   500             if ( pos >= 0 )
       
   501                 {
       
   502                 SetBrokenStateL( KDRMMessageMalformed );
       
   503                 }
       
   504             }
       
   505         } while ( res.Length() );
       
   506     }
       
   507 
       
   508 
       
   509 // -----------------------------------------------------------------------------
       
   510 // CDRMMessageParser::FindBoundaryL
       
   511 // Tries to locate the boundary string from the available data in iInputBuffer.
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 void CDRMMessageParser::FindBoundaryL()
       
   515     {
       
   516     TPtrC8 line( NULL, 0 );
       
   517     
       
   518     FOREVER
       
   519         {
       
   520         line.Set( GetLineL() );
       
   521         
       
   522         if ( line.Length() > KBoundaryMarkLength )
       
   523             {
       
   524             TInt size = 0;
       
   525             
       
   526             if ( line.Left( KBoundaryMarkLength ) == KBoundaryMark )
       
   527                 {
       
   528                 size = line.Length() - KBoundaryMarkLength - 1;
       
   529                 
       
   530                 if ( line[ line.Length() - 2 ] == '\r' )
       
   531                     {
       
   532                     --size;
       
   533                     }
       
   534                 
       
   535                 iBoundary = line.Mid( KBoundaryMarkLength, size ).AllocL();
       
   536                 
       
   537                 SetBit( EGotBoundary );
       
   538                 SetBit( EReadingHeaderPart );
       
   539                 
       
   540                 CompressInputBuffer();
       
   541                 
       
   542                 return;
       
   543                 }
       
   544             }
       
   545         else
       
   546             {
       
   547             if ( line.Length() == 0 )
       
   548                 {
       
   549                 return;
       
   550                 }
       
   551             }
       
   552         
       
   553         // Something else, not interested.
       
   554         CompressInputBuffer();
       
   555         }
       
   556     }
       
   557 
       
   558 // ----------------------------------------------------------------------------
       
   559 // CDRMMessageParser::ReadHeaderL
       
   560 // The boundary is read and the following part is (should be) either a RO part
       
   561 // or content part. The data is kept in iInputBuffer until the whole header 
       
   562 // part of the MIME header part is received. After plain "\r\n" line is 
       
   563 // received and content-type is defined, iState is updated.
       
   564 // ----------------------------------------------------------------------------
       
   565 //
       
   566 void CDRMMessageParser::ReadHeaderL()
       
   567     {
       
   568     TPtrC8 line( NULL, 0 );
       
   569     TPtrC8 ptr( NULL, 0 );
       
   570     
       
   571     FOREVER
       
   572         {
       
   573         ///////////////////////////////////////////////////////////////////
       
   574         // Process the MIME header line-by-line. Process the lines if they
       
   575         // contain some information that is found useful. Update the 
       
   576         // internal state according to findings.
       
   577         ///////////////////////////////////////////////////////////////////
       
   578         line.Set( GetLineL() );
       
   579         
       
   580         if ( line.Length() )
       
   581             {
       
   582             if ( line == KEndLine || line == KNewLine )
       
   583                 {
       
   584                 ///////////////////////////////////////////////
       
   585                 // MIME header is read. Check what to do next.
       
   586                 ///////////////////////////////////////////////
       
   587                 if ( iState & EGotContentType )
       
   588                     {
       
   589                     // Sanity check: Either EReadingRightsPart or 
       
   590                     // EReadingContentPart must defined.
       
   591                     __ASSERT_DEBUG( ( iState & EReadingRightsPart ) ||
       
   592                         ( iState & EReadingContentPart ), 
       
   593                         User::Invariant() );
       
   594                     
       
   595                     ClearBit( EReadingHeaderPart );
       
   596                     
       
   597                     CompressInputBuffer();
       
   598                     
       
   599                     // Check which part was read.
       
   600                     // If content part is being processed, some checkings 
       
   601                     // need to be made.
       
   602                     if ( iState & EReadingContentPart )
       
   603                         {
       
   604                         if ( iContentType->CompareF( KDRMContentType ) == 0 )
       
   605                             {
       
   606                             if ( iState & EGotRightsPart )
       
   607                                 {
       
   608                                 // CD DCF.
       
   609                                 SetBrokenStateL( KErrCANotSupported );
       
   610                                 }
       
   611                             
       
   612                             InitDCFBufferL();
       
   613 
       
   614                             SetBit( EDCFFile );
       
   615                             }
       
   616                         else
       
   617                             {
       
   618                             // Non-DCF FL content or normal CD content. 
       
   619                             // Create or modify the CID, save the RO.
       
   620                             HandleFlContentL();
       
   621                             
       
   622                              iDcfCreator->EncryptInitializeL(
       
   623                                 iOutputStream,
       
   624                                 *iContentType,
       
   625                                 iRightsObject );
       
   626                             SetBit( EEncryptStreamOk );
       
   627                             
       
   628                             // The RO handle iRightsObject is kept in order 
       
   629                             // to delete the rights in case of content 
       
   630                             // encryption error. In that case, this will 
       
   631                             // generate unnecessary "RO Added / RO Deleted"
       
   632                             // notifications, but so what. "More correct"
       
   633                             // way of doing would be modifying 
       
   634                             // EncryptInitialize not to 
       
   635                             // save the RO, but then the key would have to
       
   636                             // be given to it by other means. Since we are
       
   637                             // not their "friend" class, we cannot access 
       
   638                             // their members, and making them to ask our
       
   639                             // members when doing EncryptInitialize/Finalize
       
   640                             // might cause some problems perhaps.
       
   641                             }
       
   642                         
       
   643                         delete iContentType;
       
   644                         iContentType = NULL;
       
   645                         }
       
   646                     
       
   647                     return;
       
   648                     }
       
   649                 
       
   650                 // Empty MIME header.
       
   651                 SetBrokenStateL( KDRMMessageMalformed );
       
   652                 }
       
   653             
       
   654             ///////////////////////////////////
       
   655             // Check the line for content-type.
       
   656             ///////////////////////////////////
       
   657             if ( line.Length() > KContentType().Length()  &&  
       
   658                 !( line.Left( KContentType().Length() ).CompareF( KContentType ) ) )
       
   659                 {
       
   660                 if ( iState & EGotContentType )
       
   661                     {
       
   662                     // Content-type given twice.
       
   663                     SetBrokenStateL( KDRMMessageMalformed );
       
   664                     }
       
   665                 
       
   666                 ptr.Set( HeaderValueL( line ) );
       
   667                 
       
   668                 SetBit( EGotContentType );
       
   669                 
       
   670                 // Which part this is: rights or the actual content?
       
   671                 if ( ( ptr.CompareF( KDRMXMLRightsType ) == 0 ) ||
       
   672                     ( ptr.CompareF( KDRMWBXMLRightsType ) == 0 ) )
       
   673                     {
       
   674                     if ( iState & EGotRightsPart )
       
   675                         {
       
   676                         // Rights are given twice.
       
   677                         SetBrokenStateL( KDRMMessageMalformed );
       
   678                         }
       
   679                     
       
   680                     SetBit( EReadingRightsPart );
       
   681                     }
       
   682                 else
       
   683                     {
       
   684                     if ( iState & EGotContentPart )
       
   685                         {
       
   686                         SetBrokenStateL( KDRMMessageMalformed );
       
   687                         }
       
   688                     
       
   689                     SetBit( EReadingContentPart );
       
   690                     
       
   691                     // Content-type is saved for future use.
       
   692                     iContentType = ptr.AllocL();
       
   693                     }
       
   694                 }
       
   695             else
       
   696                 {
       
   697                 ////////////////////////////////////////////////
       
   698                 // Check the line for content-transfer-encoding.
       
   699                 ////////////////////////////////////////////////
       
   700                 if ( line.Length() > KContentTransferEncoding().Length() &&
       
   701                     !( line.Left( KContentTransferEncoding().Length() ).
       
   702                     CompareF( KContentTransferEncoding ) ) )
       
   703                     {
       
   704                     if ( iState & EGotContentEncoding )
       
   705                         {
       
   706                         // Double line.
       
   707                         SetBrokenStateL( KDRMMessageMalformed );
       
   708                         }
       
   709                     
       
   710                     ptr.Set( HeaderValueL( line ) );
       
   711                     
       
   712                     SetBit( EGotContentEncoding );
       
   713 
       
   714                     // Throw an error if content-transfer-encoding 
       
   715                     // is something we don't support.
       
   716                     if ( ptr.CompareF( KEncoding8bit ) &&
       
   717                         ptr.CompareF( KEncoding7bit) &&
       
   718                         ptr.CompareF( KEncodingBinary ) )
       
   719                         {
       
   720                         if ( ptr.CompareF( KEncodingBase64 ) )
       
   721                             {
       
   722                             SetBrokenStateL( KErrCANotSupported );
       
   723                             }
       
   724                         
       
   725                         // So it has to be Base64.
       
   726                         SetBit( EBase64 );
       
   727                         }
       
   728                     }
       
   729                 else
       
   730                     {
       
   731                     //////////////////////////////////////////
       
   732                     // Check the line for end boundary marker.
       
   733                     //////////////////////////////////////////
       
   734                     TBool final( EFalse );
       
   735                     
       
   736                     if ( IsBoundary( line, final ) )
       
   737                         {
       
   738                         SetBrokenStateL( KDRMMessageMalformed );
       
   739                         }
       
   740                     
       
   741                     // Else: some X-field, parameter or something else. 
       
   742                     // The line is ignored.
       
   743                     }
       
   744                 }
       
   745             
       
   746             CompressInputBuffer();
       
   747             }
       
   748             
       
   749         else
       
   750             {
       
   751             // No line available yet.
       
   752             return;
       
   753             }
       
   754         }
       
   755     }
       
   756 
       
   757 // -----------------------------------------------------------------------------
       
   758 // CDRMMessageParser::GetLineL
       
   759 // Return a descriptor representing a single line ending to \n in iInputBuffer.
       
   760 // -----------------------------------------------------------------------------
       
   761 //
       
   762 TPtrC8 CDRMMessageParser::GetLineL()
       
   763     {
       
   764     TInt pos = 0;
       
   765     TPtrC8 res( NULL, 0 );
       
   766     
       
   767     if ( iInputBuffer.Length() > iUsedFromInput )
       
   768         {
       
   769         pos = iInputBuffer.Mid( iUsedFromInput ).Find( KNewLine );
       
   770         
       
   771         if ( pos >= 0 )
       
   772             {
       
   773             res.Set( iInputBuffer.Mid( iUsedFromInput, pos - iUsedFromInput + 1 ) );
       
   774             iUsedFromInput = pos + 1;
       
   775             }
       
   776         }
       
   777     
       
   778     if ( res.Length() == 0 )
       
   779         {
       
   780         if ( iInputData.Length() )
       
   781             {
       
   782             pos = iInputData.Find( KNewLine );
       
   783             
       
   784             if ( pos < 0 )
       
   785                 {
       
   786                 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() < 
       
   787                     iInputData.Length() )
       
   788                     {
       
   789                     SetBrokenStateL( KDRMMessageMalformed );
       
   790                     }
       
   791                 
       
   792                 iInputBuffer.Append( iInputData );
       
   793                 iInputData.Set( NULL, 0 );
       
   794                 }
       
   795             else
       
   796                 {
       
   797                 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() <
       
   798                     pos + 1 )
       
   799                     {
       
   800                     SetBrokenStateL( KDRMMessageMalformed );
       
   801                     }
       
   802                 
       
   803                 iInputBuffer.Append( iInputData.Left( pos + 1 ) );
       
   804                 res.Set( iInputBuffer.Mid( iUsedFromInput ) );
       
   805                 iUsedFromInput = iInputBuffer.Length();
       
   806                 
       
   807                 iInputData.Set( iInputData.Mid( pos + 1 ) );
       
   808                 }
       
   809             }
       
   810         }
       
   811     
       
   812     return res;
       
   813     }
       
   814 
       
   815 // -----------------------------------------------------------------------------
       
   816 // CDRMMessageParser::HeaderValueL
       
   817 // Return a descriptor representing a header value in aLine.
       
   818 // -----------------------------------------------------------------------------
       
   819 //
       
   820 TPtrC8 CDRMMessageParser::HeaderValueL( const TDesC8& aLine )
       
   821     {
       
   822     TInt pos( 0 );
       
   823     TPtrC8 res( NULL, 0 );
       
   824     
       
   825     pos = aLine.Find( KColon );
       
   826     
       
   827     if ( pos <= 0 )
       
   828         {
       
   829         SetBrokenStateL( KDRMMessageMalformed );
       
   830         }
       
   831     
       
   832     pos += 1;
       
   833     
       
   834     while ( pos < aLine.Length() && 
       
   835             TChar( aLine[ pos ] ).IsSpace() )
       
   836         {
       
   837         ++pos;
       
   838         }
       
   839 
       
   840     // Don't overindex.   
       
   841     if ( pos == aLine.Length() )
       
   842         {
       
   843         // Full of whitespaces.
       
   844         SetBrokenStateL( KDRMMessageMalformed );
       
   845         }
       
   846 
       
   847     // Drop possible parameters.
       
   848     res.Set( aLine.Mid( pos ) );
       
   849     pos = res.Find( KSemiColon );
       
   850     
       
   851     if ( pos >= 0 )
       
   852         {
       
   853         res.Set( res.Left( pos ) );
       
   854         }
       
   855     
       
   856     pos = res.Length();
       
   857     
       
   858     if ( !pos )
       
   859         {
       
   860         // Just parameters, no actual value.
       
   861         SetBrokenStateL( KDRMMessageMalformed );
       
   862         }
       
   863 
       
   864     // This can't underflow, since otherwise there would be only 
       
   865     // semicolon & parameters (checked earlier).
       
   866     while( TChar( res[ pos - 1 ] ).IsSpace() )
       
   867         {
       
   868         --pos;
       
   869         }
       
   870     
       
   871     return res.Left( pos );
       
   872     }
       
   873 
       
   874 // -----------------------------------------------------------------------------
       
   875 // CDRMMessageParser::CompressInputBuffer
       
   876 // Compress iInputBuffer.
       
   877 // -----------------------------------------------------------------------------
       
   878 //
       
   879 void CDRMMessageParser::CompressInputBuffer()
       
   880     {
       
   881     if ( iUsedFromInput )
       
   882         {
       
   883         const TInt size = iInputBuffer.Length() - iUsedFromInput;
       
   884         
       
   885         Mem::Copy( const_cast< TUint8* >( iInputBuffer.Ptr() ),
       
   886             iInputBuffer.Ptr() + iUsedFromInput,
       
   887             size );
       
   888         
       
   889         iInputBuffer.SetLength( size );
       
   890         iUsedFromInput = 0;
       
   891         }
       
   892     }
       
   893 
       
   894 // -----------------------------------------------------------------------------
       
   895 // CDRMMessageParser::PrepareContentDataL
       
   896 // Fills the iInputBuffer from iInputData.
       
   897 // -----------------------------------------------------------------------------
       
   898 //
       
   899 void CDRMMessageParser::PrepareContentDataL()
       
   900     {
       
   901     if ( iInputData.Length() )
       
   902         {
       
   903         if ( iInputBuffer.Length() == iInputBuffer.MaxSize() )
       
   904             {
       
   905             SetBrokenStateL( KDRMMessageMalformed );
       
   906             }
       
   907         
       
   908         const TInt size = Min( iInputBuffer.MaxSize() - iInputBuffer.Length(), 
       
   909                                iInputData.Length() );
       
   910         
       
   911         iInputBuffer.Append( iInputData.Left( size ) );
       
   912         
       
   913         iInputData.Set( iInputData.Mid( size ) );
       
   914         }
       
   915     }
       
   916     
       
   917 // -----------------------------------------------------------------------------
       
   918 // CDRMMessageParser::HandleBase64DataL
       
   919 // Decode base64 encoded data from and to aData descriptor.
       
   920 // 
       
   921 // -----------------------------------------------------------------------------
       
   922 //
       
   923 TInt CDRMMessageParser::HandleBase64DataL( TPtrC8& aData )
       
   924     {
       
   925     TUint8* consumed = const_cast< TUint8* >( aData.Ptr() );
       
   926     TUint32 temp1 = 0;
       
   927     TUint8 temp2 = 0;
       
   928 
       
   929     for ( temp1 = 0, temp2 = 0; ( TInt )temp1 < aData.Length(); ++temp1 )
       
   930         {
       
   931         if ( ValidB64CharL( *( aData.Ptr() + temp1 ) ) )
       
   932             {
       
   933             ++temp2;
       
   934             if ( temp2 == 4 )
       
   935                 {
       
   936                 consumed = const_cast< TUint8* >( aData.Ptr() ) + temp1;
       
   937                 temp2 = 0;
       
   938                 }
       
   939             }
       
   940         }
       
   941     
       
   942     if ( consumed != aData.Ptr() )
       
   943         {
       
   944         User::LeaveIfError( b64decode( const_cast< TUint8* >( aData.Ptr() ), 
       
   945                                        consumed - aData.Ptr() + 1,
       
   946                                        const_cast< TUint8* >( aData.Ptr() ), 
       
   947                                        &temp1 ) );
       
   948         
       
   949         aData.Set( aData.Ptr(), temp1 );
       
   950 
       
   951         temp1 = consumed - aData.Ptr() + 1;
       
   952         }
       
   953         
       
   954     else
       
   955         {
       
   956         aData.Set( aData.Ptr(), 0 );
       
   957         temp1 = 0;
       
   958         }
       
   959 
       
   960     return static_cast< TInt >( temp1 );
       
   961     }
       
   962 
       
   963 // -----------------------------------------------------------------------------
       
   964 // CDRMMessageParser::StripEndLineL
       
   965 // Remove \r\n from the end of the line. Update aBuf accordingly.
       
   966 // It is allowed that only \n exists, since some WAP gateways used to
       
   967 // strip \r's.
       
   968 // -----------------------------------------------------------------------------
       
   969 //
       
   970 void CDRMMessageParser::StripEndLineL( TPtrC8& aBuf )
       
   971     {
       
   972     TInt newSize( aBuf.Length() );
       
   973     
       
   974     if ( aBuf.Right( 1 ) == KNewLine )
       
   975         {
       
   976         --newSize;
       
   977         
       
   978         if ( ( aBuf.Length() > 1 ) && 
       
   979             ( aBuf.Right( 2 ) == KEndLine ) )
       
   980             {
       
   981             --newSize;
       
   982             }
       
   983         
       
   984         aBuf.Set( aBuf.Left( newSize ) );
       
   985         }
       
   986     else
       
   987         {
       
   988         SetBrokenStateL( KDRMMessageMalformed );
       
   989         }
       
   990     }
       
   991 
       
   992 // -----------------------------------------------------------------------------
       
   993 // CDRMMessageParser::IsBoundary
       
   994 // Check if the given line is a boundary line. Also check if the line is
       
   995 // the end boundary.
       
   996 // -----------------------------------------------------------------------------
       
   997 //
       
   998 TBool CDRMMessageParser::IsBoundary( const TDesC8& aLine, TBool& aLast ) const 
       
   999     {
       
  1000     TBool res = EFalse;
       
  1001     
       
  1002     __ASSERT_DEBUG( iBoundary, User::Invariant() );
       
  1003     
       
  1004     if ( iState & EGotBoundary )
       
  1005         {
       
  1006         if ( aLine.Length() > KBoundaryMarkLength + iBoundary->Length() )
       
  1007             {
       
  1008             TPtrC8 tmp( NULL, 0 );
       
  1009             
       
  1010             if ( ( aLine.Left( KBoundaryMarkLength ) == KBoundaryMark ) &&
       
  1011                 ( aLine.Mid( KBoundaryMarkLength, iBoundary->Length() ).
       
  1012                 Compare( *iBoundary ) == 0 ) )
       
  1013                 {
       
  1014                 res = ETrue;
       
  1015                 
       
  1016                 tmp.Set( aLine.Right( aLine.Length() - 
       
  1017                     KBoundaryMarkLength - 
       
  1018                     iBoundary->Length() ) );
       
  1019                 
       
  1020                 if ( ( tmp.Length() >= KBoundaryMarkLength ) &&
       
  1021                     ( tmp.Left( KBoundaryMarkLength ) == KBoundaryMark ) )
       
  1022                     {
       
  1023                     aLast = ETrue;
       
  1024                     }
       
  1025                 }
       
  1026             }
       
  1027         }
       
  1028     
       
  1029     return res;
       
  1030     }
       
  1031 
       
  1032 // -----------------------------------------------------------------------------
       
  1033 // CDRMMessageParser::HandleFlContentL
       
  1034 // Process FL/CD rights object.
       
  1035 // -----------------------------------------------------------------------------
       
  1036 //
       
  1037 void CDRMMessageParser::HandleFlContentL()
       
  1038     {
       
  1039     __ASSERT_DEBUG( !( iState & EDCFFile ), User::Invariant() );
       
  1040     
       
  1041     if ( iRightsData )
       
  1042         {
       
  1043         HBufC8* cid( NULL );
       
  1044         HBufC8* buf( NULL );
       
  1045         
       
  1046         // RO was found from DRM message.
       
  1047         CreateCDCIDL( cid );
       
  1048         CleanupStack::PushL( cid );
       
  1049       
       
  1050         buf = iRightsData;
       
  1051         CleanupStack::PushL( buf );
       
  1052         iRightsData = NULL;
       
  1053         
       
  1054         ProcessRightsDataL( *cid, 
       
  1055                             *buf );
       
  1056         
       
  1057         CleanupStack::PopAndDestroy(); // buf
       
  1058         CleanupStack::PopAndDestroy(); // cid
       
  1059         }
       
  1060     else
       
  1061         {
       
  1062         TInt error = RetrieveFlRights();
       
  1063         if ( error )
       
  1064             {
       
  1065             SetBrokenStateL( error );
       
  1066             }
       
  1067         }
       
  1068     }
       
  1069 
       
  1070 // -----------------------------------------------------------------------------
       
  1071 // CDRMMessageParser::ProcessRightsData
       
  1072 // Process DRM message -style rights object and fetch it to iRightsObject if 
       
  1073 // necessary.
       
  1074 // -----------------------------------------------------------------------------
       
  1075 //
       
  1076 void CDRMMessageParser::ProcessRightsDataL( 
       
  1077                             const TDesC8& aCID,
       
  1078                             const TDesC8& aData )
       
  1079     {
       
  1080     __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
       
  1081     
       
  1082     TInt start = aData.Find(KRightsStartTag);
       
  1083     TInt end = aData.LocateReverse('>');
       
  1084     
       
  1085     if ( start >= 0 && end > start )
       
  1086         {
       
  1087         TDRMUniqueID localID( 0 );
       
  1088         CDrmRightsParser* parser( NULL );
       
  1089         CDRMAsset* asset( NULL );
       
  1090         RDRMRightsClient client;
       
  1091         TPtrC8 ptr( &aData[start], end - start + 1 );
       
  1092         TBuf8< KDCFKeySize > key;
       
  1093         key.SetLength(KDCFKeySize);
       
  1094         RPointerArray< CDRMRights > rights;
       
  1095         
       
  1096         TCleanupItem cleanup( DoResetAndDestroy, &rights );
       
  1097         CleanupStack::PushL( cleanup );
       
  1098         
       
  1099         User::LeaveIfError( client.Connect() );
       
  1100         CleanupClosePushL( client );
       
  1101         
       
  1102         parser = CDrmRightsParser::NewL();
       
  1103         CleanupStack::PushL( parser );
       
  1104         
       
  1105         parser->ParseL( ptr, rights );
       
  1106         
       
  1107         if (rights.Count()==0)
       
  1108         	{
       
  1109         	User::Leave(KErrCorrupt);
       
  1110         	}
       
  1111         
       
  1112         client.GetRandomDataL(key);
       
  1113 
       
  1114         User::LeaveIfError( client.AddRecord(
       
  1115                             key, 
       
  1116                             rights[0]->GetPermission(), 
       
  1117                             aCID, 
       
  1118                             localID) );
       
  1119         
       
  1120         iRightsObject = CDRMRights::NewL();
       
  1121         
       
  1122         asset = CDRMAsset::NewLC();
       
  1123         asset->iUid = aCID.AllocL();
       
  1124         
       
  1125         iRightsObject->SetAssetL(*asset);
       
  1126         iRightsObject->SetPermissionL(rights[0]->GetPermission());
       
  1127         
       
  1128         CleanupStack::PopAndDestroy( 4 ); // asset, parser, client, rights
       
  1129         }
       
  1130     else
       
  1131         {
       
  1132         SetBrokenStateL( KErrArgument );
       
  1133         }
       
  1134     }
       
  1135 
       
  1136 // -----------------------------------------------------------------------------
       
  1137 // CDRMMessageParser::ProcessContentDataL
       
  1138 // Handle DCF file's CID manipulation in "DCF in DRM message" case. 
       
  1139 // Send the data to EncryptUpdateL if encryption is needed.
       
  1140 // -----------------------------------------------------------------------------
       
  1141 //
       
  1142 void CDRMMessageParser::ProcessContentDataL( TPtrC8& aData )
       
  1143     {
       
  1144     // First, check if the content is DCF stuff.
       
  1145     if ( iState & EDCFFile )
       
  1146         {
       
  1147         // Sanity check: DCF File with RO is illegal.
       
  1148         __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
       
  1149 
       
  1150         ProcessDCFDataL( aData );
       
  1151         }
       
  1152     else
       
  1153         {
       
  1154         // No, plain FL content.
       
  1155         iDcfCreator->EncryptUpdateL( aData );
       
  1156         }
       
  1157     }
       
  1158 
       
  1159 // -----------------------------------------------------------------------------
       
  1160 // CDRMMessageParser::ValidB64CharL
       
  1161 // Determine if the given character is valid base64 character, and leave
       
  1162 // if it is not.
       
  1163 // -----------------------------------------------------------------------------
       
  1164 //
       
  1165 TBool CDRMMessageParser::ValidB64CharL( const TUint8 aChar )
       
  1166     {
       
  1167     // Allowed characters are '0'...'9', 'A'...'Z', 'a'...'z', '+', '/', '='
       
  1168     if ( ( aChar >= 48 && aChar <= 57 ) || 
       
  1169          ( aChar >= 65 && aChar <= 90 ) ||
       
  1170          ( aChar >= 97 && aChar <= 122 ) || 
       
  1171          ( aChar == 43 ) ||
       
  1172          ( aChar == 47 ) ||
       
  1173          ( aChar == 61 ) )
       
  1174         {
       
  1175         return ETrue;
       
  1176         }
       
  1177 
       
  1178     if ( ( aChar != 0x0D ) && ( aChar != 0x0A ) )
       
  1179         {
       
  1180         SetBrokenStateL( KDRMMessageMalformed );        
       
  1181         }
       
  1182 
       
  1183     return EFalse;
       
  1184     }
       
  1185 
       
  1186 // -----------------------------------------------------------------------------
       
  1187 // DRMCommon::ProcessMessage
       
  1188 // 
       
  1189 // -----------------------------------------------------------------------------
       
  1190 EXPORT_C TInt CDRMMessageParser::ProcessMessage(
       
  1191     HBufC8*& aDRMMessage)
       
  1192     {
       
  1193     TInt error( KErrNone );
       
  1194     TRAP( error, DoProcessMessageL( aDRMMessage ) );
       
  1195     
       
  1196     return error;
       
  1197     }
       
  1198     
       
  1199 // -----------------------------------------------------------------------------
       
  1200 // DRMCommon::ProcessRightsObject
       
  1201 // Processes a rights objects and saves it in the rights database.
       
  1202 // -----------------------------------------------------------------------------
       
  1203 EXPORT_C TInt CDRMMessageParser::ProcessRightsObject(
       
  1204     const TDesC8& aRightsObject, 
       
  1205     RPointerArray<CDRMRights>& aRightsDetail)
       
  1206     {
       
  1207     TInt error( KErrNone );
       
  1208     TRAP( error, DoProcessRightsObjectL( aRightsObject,
       
  1209                                          aRightsDetail ) );
       
  1210                                          
       
  1211     return error;
       
  1212     }
       
  1213 
       
  1214 void CDRMMessageParser::SetBit( TUint32 aBit )
       
  1215     {
       
  1216     iState |= aBit;
       
  1217     }
       
  1218     
       
  1219 void CDRMMessageParser::ClearBit( TUint32 aBit )
       
  1220     {
       
  1221     iState &= ~aBit;
       
  1222     }
       
  1223 
       
  1224 void CDRMMessageParser::Reset()
       
  1225     {
       
  1226     delete iDCFBuffer;
       
  1227     iDCFBuffer = NULL;
       
  1228     
       
  1229     delete iDcfCreator;
       
  1230     iDcfCreator = NULL;
       
  1231     
       
  1232     delete iRightsData;
       
  1233     iRightsData = NULL;
       
  1234     
       
  1235     delete iRightsObject;
       
  1236     iRightsObject = NULL;
       
  1237     
       
  1238     delete iBoundary;
       
  1239     iBoundary = NULL;
       
  1240     
       
  1241     delete iContentType;
       
  1242     iContentType = NULL;
       
  1243     
       
  1244     iInputBuffer.SetLength( 0 );
       
  1245     
       
  1246     iState = ESearchingBoundary;
       
  1247     iDCFHeaderSize[ 0 ] = KMaxTUint32;
       
  1248     iDCFHeaderSize[ 1 ] = KMaxTUint32;
       
  1249     }
       
  1250 
       
  1251 void CDRMMessageParser::DoProcessMessageL( HBufC8*& aDRMMessage )
       
  1252     {
       
  1253     TDeleteFileData fileData;
       
  1254     RFileWriteStream output;
       
  1255     RFile file;
       
  1256     TInt size( 0 );
       
  1257     
       
  1258     User::LeaveIfError( fileData.aFs.Connect() );
       
  1259     CleanupClosePushL( fileData.aFs );
       
  1260 
       
  1261     TCleanupItem cleanup( DoDeleteFile, &fileData );
       
  1262     CleanupStack::PushL( cleanup );
       
  1263     
       
  1264 #ifndef RD_MULTIPLE_DRIVE
       
  1265 
       
  1266     User::LeaveIfError( output.Temp( fileData.aFs, 
       
  1267                                      KTempPath, 
       
  1268                                      fileData.aName, 
       
  1269                                      EFileWrite ) );
       
  1270     
       
  1271 #else //RD_MULTIPLE_DRIVE
       
  1272     
       
  1273     TInt driveNumber( -1 );
       
  1274     TChar driveLetter;
       
  1275     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
       
  1276 	fileData.aFs.DriveToChar( driveNumber, driveLetter );
       
  1277     
       
  1278 	TFileName tempPath;
       
  1279 	tempPath.Format( KTempPath, (TUint)driveLetter );
       
  1280 
       
  1281     User::LeaveIfError( output.Temp( fileData.aFs, 
       
  1282                                    tempPath, 
       
  1283                                    fileData.aName, 
       
  1284                                    EFileWrite ) );
       
  1285     
       
  1286 #endif
       
  1287     
       
  1288     CleanupClosePushL( output );
       
  1289     
       
  1290     InitializeMessageParserL( output );
       
  1291     ProcessMessageDataL( *aDRMMessage );
       
  1292     FinalizeMessageParserL();
       
  1293     
       
  1294     CleanupStack::PopAndDestroy(); // output
       
  1295     
       
  1296     User::LeaveIfError( file.Open( fileData.aFs, fileData.aName, EFileRead ) );
       
  1297     CleanupClosePushL( file );
       
  1298     
       
  1299     User::LeaveIfError( file.Size( size ) );
       
  1300     
       
  1301     if ( size > aDRMMessage->Des().MaxSize() )
       
  1302         {
       
  1303         HBufC8* tmp( NULL );
       
  1304         
       
  1305         delete aDRMMessage; 
       
  1306         aDRMMessage = NULL;
       
  1307         
       
  1308         tmp = HBufC8::NewLC( size );
       
  1309         TPtr8 data( tmp->Des() );
       
  1310         
       
  1311         User::LeaveIfError( file.Read( data ) );
       
  1312         CleanupStack::Pop(); // tmp
       
  1313         
       
  1314         aDRMMessage = tmp;
       
  1315         }
       
  1316     else
       
  1317         {
       
  1318         TPtr8 data( aDRMMessage->Des() );
       
  1319         User::LeaveIfError( file.Read( data ) );
       
  1320         }
       
  1321     
       
  1322     CleanupStack::PopAndDestroy( 3 ); // file, cleanup, fileData.aFs
       
  1323     }
       
  1324 
       
  1325 void CDRMMessageParser::DoProcessRightsObjectL( 
       
  1326     const TDesC8& aRightsObject, 
       
  1327     RPointerArray<CDRMRights>& aRightsDetail )
       
  1328     {
       
  1329     CDrmRightsParser* parser = NULL;
       
  1330     TInt start;
       
  1331     TInt end;
       
  1332     TPtrC8 ptr(0, 0);
       
  1333     
       
  1334     start = aRightsObject.Find(KRightsStartTag);
       
  1335     end = aRightsObject.LocateReverse('>');
       
  1336     
       
  1337     TCleanupItem cleanup( DoResetAndDestroy, &aRightsDetail );
       
  1338     CleanupStack::PushL( cleanup );
       
  1339 
       
  1340     if ( start != KErrNotFound && end != KErrNotFound )
       
  1341         {
       
  1342         // xml
       
  1343         parser = CDrmRightsParser::NewL();
       
  1344         CleanupStack::PushL(parser);
       
  1345         
       
  1346         ptr.Set(&aRightsObject[start], end - start + 1);    
       
  1347         
       
  1348         parser->ParseAndStoreL(ptr, aRightsDetail);
       
  1349         
       
  1350         if (aRightsDetail.Count() == 0)
       
  1351             {
       
  1352             User::Leave( KErrArgument );
       
  1353             }
       
  1354         
       
  1355         CleanupStack::PopAndDestroy(); // parser
       
  1356         }
       
  1357     else if (start == KErrNotFound )
       
  1358         {
       
  1359         // wbxml
       
  1360         parser = CDrmRightsParser::NewL(CDrmRightsParser::EWbxmlParser);
       
  1361         CleanupStack::PushL(parser);
       
  1362         
       
  1363         parser->ParseAndStoreL(aRightsObject, aRightsDetail);
       
  1364         if (aRightsDetail.Count() == 0)
       
  1365             {
       
  1366             User::Leave( KErrArgument );
       
  1367             }
       
  1368         
       
  1369         CleanupStack::PopAndDestroy(); // parser
       
  1370         }
       
  1371     else
       
  1372         {
       
  1373         User::Leave( KErrArgument );
       
  1374         }
       
  1375     
       
  1376     CleanupStack::Pop(); // cleanup
       
  1377     }
       
  1378     
       
  1379 void CDRMMessageParser::DeletePermission()
       
  1380     {
       
  1381     if ( iRightsObject )
       
  1382         {
       
  1383         if ( !( iState & EFLContent ) )
       
  1384             {
       
  1385             HBufC8* URI = NULL;
       
  1386             
       
  1387             if ( !( iRightsObject->GetContentURI( URI ) ) )
       
  1388                 {
       
  1389                 __ASSERT_DEBUG( URI, User::Invariant() );
       
  1390                 
       
  1391                 RDRMRightsClient client;
       
  1392                 
       
  1393                 TInt error = client.Connect();
       
  1394                 
       
  1395                 if ( !error )
       
  1396                     {
       
  1397                     // Don't care if it fails.
       
  1398                     client.DeleteDbEntry( *URI, iRightsObject->GetLocalID() );
       
  1399                     
       
  1400                     client.Close();
       
  1401                     }
       
  1402                 
       
  1403                 delete URI;
       
  1404                 URI = NULL;
       
  1405                 }
       
  1406             }
       
  1407         
       
  1408         delete iRightsObject;
       
  1409         iRightsObject = NULL;
       
  1410         }
       
  1411     }
       
  1412 
       
  1413 void CDRMMessageParser::SetBrokenStateL( const TInt aError )
       
  1414     {
       
  1415     SetBit( EBroken );
       
  1416     DeletePermission();
       
  1417     
       
  1418     User::Leave( aError );
       
  1419     }
       
  1420 
       
  1421 void CDRMMessageParser::InitDCFBufferL()
       
  1422     {
       
  1423     iDCFBuffer = HBufC8::New( KInitialDCFBufferSize );
       
  1424 
       
  1425     if ( !iDCFBuffer )
       
  1426         {
       
  1427         SetBrokenStateL( KErrNoMemory );
       
  1428         }
       
  1429     }
       
  1430 
       
  1431 void CDRMMessageParser::CreateCDCIDL( HBufC8*& aCID )
       
  1432     {
       
  1433     aCID = HBufC8::NewL( KCDContentIDLength );
       
  1434     TPtr8 des( aCID->Des() );
       
  1435     TBuf8<KCDPlainIDLength> id;
       
  1436     id.SetLength(KCDPlainIDLength);
       
  1437 
       
  1438     RDRMRightsClient client;
       
  1439     CleanupClosePushL(client);
       
  1440     User::LeaveIfError( client.Connect() );
       
  1441     client.GetRandomDataL(id);
       
  1442     CleanupStack::PopAndDestroy();
       
  1443 
       
  1444     des = KFLPrefix;
       
  1445     
       
  1446     for (TInt i = 0; i < KCDPlainIDLength; i++)
       
  1447         {
       
  1448         des.AppendNumFixedWidth( id[i], EDecimal, 1 );
       
  1449         }
       
  1450 
       
  1451     des.Append( KFLSuffix );
       
  1452     }
       
  1453     
       
  1454 TInt CDRMMessageParser::RetrieveFlRights()
       
  1455     {
       
  1456     __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
       
  1457     
       
  1458     RDRMRightsClient client;
       
  1459     TInt error( client.Connect() );
       
  1460     
       
  1461     if ( !error )
       
  1462         {
       
  1463         TRAP( error, EnsureFLRightsExistL( client, &iRightsObject ) );
       
  1464                 
       
  1465         client.Close();
       
  1466         }
       
  1467         
       
  1468     return error;
       
  1469     }
       
  1470 
       
  1471 void CDRMMessageParser::ProcessDCFDataL( TPtrC8& aDCFData )
       
  1472     {
       
  1473     TBool doCommit( EFalse );
       
  1474     
       
  1475     // Loop until all available data is either cached or processed.
       
  1476     // What happens is
       
  1477     // - modify Content-URI
       
  1478     // - modify DCF header part
       
  1479     // - dump the rest of the available data to output.
       
  1480     while ( iDCFBuffer->Length() || aDCFData.Length() )
       
  1481         {
       
  1482         if ( !( iState & EDCFURIModified ) )
       
  1483             {
       
  1484             //////////////////////////////////////////////////////////////////
       
  1485             // Modify ContentURI.
       
  1486             //////////////////////////////////////////////////////////////////
       
  1487             FillDCFBufferL( aDCFData );
       
  1488         
       
  1489             if ( iDCFBuffer->Length() > 3 )
       
  1490                 {
       
  1491                 TInt pos = 0;
       
  1492                 TUint8* data = const_cast< TUint8* > ( iDCFBuffer->Ptr() );
       
  1493                 
       
  1494                 if ( data[ 0 ] != 1 )
       
  1495                     {
       
  1496                     SetBrokenStateL( KDRMMessageMalformed );
       
  1497                     }
       
  1498                 
       
  1499                 // Cache the data until 
       
  1500                 // - version, 
       
  1501                 // - ContentTypeLen, 
       
  1502                 // - ContentURILen, 
       
  1503                 // - ContentType and 
       
  1504                 // - ContentURI 
       
  1505                 // have been received.
       
  1506                 pos = data[ 1 ] + 3;
       
  1507                 if ( iDCFBuffer->Length() < pos + data[ 2 ] )
       
  1508                     {
       
  1509                     return;
       
  1510                     }
       
  1511                 
       
  1512                 // Sanity check. URI has to be more than four ("cid:") octets.
       
  1513                 if ( data[ 2 ] < 5 )
       
  1514                     {
       
  1515                     SetBrokenStateL( KDRMMessageMalformed );
       
  1516                     }
       
  1517                 
       
  1518                 if ( Mem::CompareF( &data[ pos ], 
       
  1519                                     KCIDStringLength,
       
  1520                                     KCIDString().Ptr(), 
       
  1521                                     KCIDStringLength ) == 0 )
       
  1522                     {
       
  1523                     // The data length doesn't change, so Mem::Copy() is safe.
       
  1524                     Mem::Copy( &data[ pos ], 
       
  1525                                KFLPrefix().Ptr(), 
       
  1526                                KFLKPrefixLength );
       
  1527                     
       
  1528                     iOutputStream.WriteL( iDCFBuffer->Left( pos + data[ 2 ] ) );
       
  1529                     
       
  1530                     doCommit = ETrue;
       
  1531 
       
  1532                     CompressDCFBuffer( pos + data[ 2 ] );
       
  1533                     
       
  1534                     SetBit( EDCFURIModified );
       
  1535                     }
       
  1536                 else
       
  1537                     {
       
  1538                     // Discard the broken DCF
       
  1539                     SetBrokenStateL( KDRMMessageMalformed );
       
  1540                     }
       
  1541                 }
       
  1542             else
       
  1543                 {
       
  1544                 // Not enough data yet.
       
  1545                 return;
       
  1546                 }
       
  1547             }
       
  1548         else
       
  1549             {
       
  1550             //////////////////////////////////////////////////////////////////
       
  1551             // URI is now modified. Modify DCF headers if necessary.
       
  1552             //////////////////////////////////////////////////////////////////
       
  1553             if ( !( iState & EDCFHeadersModified ) )
       
  1554                 {
       
  1555                 FillDCFBufferL( aDCFData );
       
  1556                 
       
  1557                 // Figure out how much data there is in the header part and/or
       
  1558                 // in the data part.
       
  1559                 if ( ( iDCFHeaderSize[ 0 ] == KMaxTUint32 ) &&
       
  1560                      ( iDCFHeaderSize[ 1 ] == KMaxTUint32 ) )
       
  1561                     {
       
  1562                     TUint8 used( 0 );
       
  1563                     
       
  1564                     // uintvar has 1...5 octets and we need two uintvars before
       
  1565                     // anything can be done. Still, there has to be at least 
       
  1566                     // 12 octets of data in total to make the DCF legal. But here
       
  1567                     // we just check the two uintvars.
       
  1568                     if ( iDCFBuffer->Length() < 10 )
       
  1569                         {
       
  1570                         // Not enough data yet.
       
  1571                         // No need to flush aDCFData at this point, since it 
       
  1572                         // simply cannot contain anything at this point.
       
  1573                         __ASSERT_DEBUG( !aDCFData.Length(), User::Invariant() );
       
  1574                         break;
       
  1575                         }
       
  1576                     
       
  1577                     // Read header field length & data length.
       
  1578                     for ( TUint8 count = 0; count < 2; ++count )
       
  1579                         {
       
  1580                         TInt size( 0 );
       
  1581                         
       
  1582                         TWspPrimitiveDecoder decoder( 
       
  1583                                 iDCFBuffer->Mid( used ) );
       
  1584                         size = decoder.UintVar( iDCFHeaderSize[ count ] );
       
  1585                         
       
  1586                         // Sanity check.
       
  1587                         if ( size < 1 || iDCFHeaderSize[ count ] >= KMaxTInt )
       
  1588                             {
       
  1589                             SetBrokenStateL( KDRMMessageMalformed );
       
  1590                             }
       
  1591                         
       
  1592                         used += size;
       
  1593                         }
       
  1594                     
       
  1595                     CompressDCFBuffer( used );
       
  1596                     }
       
  1597                 else
       
  1598                     {
       
  1599                     // We know the original header size now.
       
  1600                     // Wait until the whole header is read.
       
  1601                     if ( static_cast< TUint32 >( iDCFBuffer->Length() ) < 
       
  1602                          iDCFHeaderSize[ 0 ] )
       
  1603                         {
       
  1604                         if ( !aDCFData.Length() )
       
  1605                             {
       
  1606                             // All available data is now processed.
       
  1607                             break;
       
  1608                             }
       
  1609                         }
       
  1610                     else
       
  1611                         {
       
  1612                         TUint offset( 0 );
       
  1613                         TUint length( 0 );
       
  1614                         HBufC8* newHeader = NULL;
       
  1615 
       
  1616                         if ( FindDCFHeader( KRightsIssuer, 
       
  1617                                             offset, 
       
  1618                                             length ) )
       
  1619                             {
       
  1620                             // The header field exists.
       
  1621                             TInt pos( 0 );
       
  1622                             TPtr8 trim( const_cast< TUint8* >( 
       
  1623                                             iDCFBuffer->Ptr() ) + offset,
       
  1624                                             length, 
       
  1625                                             length );
       
  1626 
       
  1627                             iDCFHeaderSize[ 0 ] -= length; // remove old data.
       
  1628                             
       
  1629                             // No colon, no header value. 
       
  1630                             pos = trim.Find( KColon );
       
  1631                             if ( pos > 0 )
       
  1632                                 {
       
  1633                                 trim.Set( const_cast< TUint8* >( trim.Ptr() ) + pos + 1, 
       
  1634                                           trim.Length() - pos - 1,
       
  1635                                           trim.Length() - pos - 1 );
       
  1636 
       
  1637                                 // Skip whitespaces
       
  1638                                 trim.TrimLeft();
       
  1639                                 trim.TrimRight();
       
  1640                                 
       
  1641                                 if ( trim.Length() )
       
  1642                                     {
       
  1643                                     // Something to process
       
  1644                                     newHeader = EncryptDCFFieldLC( trim );
       
  1645                                     
       
  1646                                     iDCFHeaderSize[ 0 ] += KRightsIssuer().Length();
       
  1647                                     iDCFHeaderSize[ 0 ] += newHeader->Length();
       
  1648                                     iDCFHeaderSize[ 0 ] += 3; // ":" and CRLF
       
  1649                                     }
       
  1650                                 }
       
  1651                             }
       
  1652                         
       
  1653                         // Write the uintvars to output.
       
  1654                         for ( TUint8 loop = 0; loop < 2; ++loop )
       
  1655                             {
       
  1656                             TWspPrimitiveEncoder encoder;
       
  1657                             HBufC8* var( encoder.UintVarL( iDCFHeaderSize[ loop ] ) );
       
  1658                             
       
  1659                             CleanupStack::PushL( var );
       
  1660                             
       
  1661                             iOutputStream.WriteL( *var );
       
  1662                             
       
  1663                             CleanupStack::PopAndDestroy(); // var
       
  1664                             }
       
  1665                         
       
  1666                         // Dump the header data to output stream.
       
  1667                         iOutputStream.WriteL( iDCFBuffer->Left( offset ) );
       
  1668                         
       
  1669                         if ( newHeader )
       
  1670                             {
       
  1671                             iOutputStream.WriteL( KRightsIssuer );
       
  1672                             iOutputStream.WriteL( KColon );
       
  1673                             iOutputStream.WriteL( *newHeader );
       
  1674                             
       
  1675                             CleanupStack::PopAndDestroy(); // newHeader
       
  1676                             newHeader = NULL;
       
  1677                             
       
  1678                             iOutputStream.WriteL( KEndLine );
       
  1679                             }
       
  1680 
       
  1681                         iOutputStream.WriteL( 
       
  1682                             iDCFBuffer->Right( iDCFBuffer->Length() - 
       
  1683                                                 offset - 
       
  1684                                                 length ) );
       
  1685                         
       
  1686                         doCommit = ETrue;
       
  1687                         
       
  1688                         CompressDCFBuffer( iDCFBuffer->Length() );
       
  1689                         SetBit( EDCFHeadersModified );
       
  1690                         }
       
  1691                     }
       
  1692                 }
       
  1693             else
       
  1694                 {
       
  1695                 // Dump the rest of the data.
       
  1696                 __ASSERT_DEBUG( !( iDCFBuffer->Length() ), User::Invariant() );
       
  1697 
       
  1698                 iOutputStream.WriteL( aDCFData );
       
  1699                 
       
  1700                 aDCFData.Set( NULL, 0 );
       
  1701                 
       
  1702                 doCommit = ETrue;
       
  1703                 }
       
  1704             }
       
  1705         }
       
  1706 
       
  1707     if ( doCommit )
       
  1708         {
       
  1709         iOutputStream.CommitL();
       
  1710         }
       
  1711     }
       
  1712 
       
  1713 void CDRMMessageParser::FillDCFBufferL( TPtrC8& aData )
       
  1714     {
       
  1715     if ( aData.Length() )
       
  1716         {
       
  1717         TInt size( 0 );
       
  1718 
       
  1719         if ( iDCFBuffer->Length() == iDCFBuffer->Des().MaxSize() )
       
  1720             {
       
  1721             HBufC8* ptr = iDCFBuffer->ReAlloc( iDCFBuffer->Length() + 
       
  1722                             KDefaultInputBufferSize );
       
  1723 
       
  1724             if ( !ptr )
       
  1725                 {
       
  1726                 SetBrokenStateL( KErrNoMemory );
       
  1727                 }
       
  1728 
       
  1729             iDCFBuffer = ptr;
       
  1730             }
       
  1731         
       
  1732         size = Min( iDCFBuffer->Des().MaxSize() - iDCFBuffer->Length(), 
       
  1733                     aData.Length() );
       
  1734         
       
  1735         iDCFBuffer->Des().Append( aData.Left( size ) );
       
  1736         
       
  1737         aData.Set( aData.Right( aData.Length() - size ) );
       
  1738         }
       
  1739     }
       
  1740     
       
  1741 void CDRMMessageParser::CompressDCFBuffer( const TInt aHowMuch )
       
  1742     {
       
  1743     __ASSERT_DEBUG( aHowMuch <= iDCFBuffer->Des().MaxSize(), User::Invariant() );
       
  1744 
       
  1745     *iDCFBuffer = iDCFBuffer->Des().Mid( aHowMuch );
       
  1746     }
       
  1747     TBool CDRMMessageParser::FindDCFHeader( const TDesC8& aString,
       
  1748                                         TUint& aOffset,
       
  1749                                         TUint& aLength )
       
  1750     {
       
  1751     TPtrC8 des( const_cast< TUint8* >( iDCFBuffer->Ptr() ),  
       
  1752                 Min( iDCFBuffer->Length(), iDCFHeaderSize[ 0 ] ) );
       
  1753 
       
  1754     aOffset = 0;
       
  1755     aLength = 0;
       
  1756 
       
  1757     while ( des.Length() )
       
  1758         {
       
  1759         TInt pos = des.Find( KEndLine );
       
  1760         if ( pos < 0 )
       
  1761             {
       
  1762             // Last header doesn't end to "\r\n"
       
  1763             pos = des.Length();
       
  1764             if ( pos < 0 )
       
  1765                 {
       
  1766                 return EFalse;
       
  1767                 }
       
  1768             }
       
  1769         else
       
  1770             {
       
  1771             pos += KEndLineLength;
       
  1772             }
       
  1773             
       
  1774         if ( ( pos < aString.Length() ) || 
       
  1775              ( des.Left( aString.Length() ).CompareF( aString ) != 0 ) )
       
  1776              {
       
  1777             // Skip the line, since this can't be the one we're looking for.
       
  1778             des.Set( des.Right( des.Length() - 
       
  1779                                 pos ) );
       
  1780             }
       
  1781         else
       
  1782             {
       
  1783             aOffset = des.Ptr() - iDCFBuffer->Ptr();
       
  1784             aLength = pos;
       
  1785             
       
  1786             return ETrue;
       
  1787             }
       
  1788         }
       
  1789     
       
  1790     // Never reached.
       
  1791     return EFalse;
       
  1792     }
       
  1793     
       
  1794 void CDRMMessageParser::EnsureFLRightsExistL( 
       
  1795     RDRMRightsClient& aClient, 
       
  1796     CDRMRights** aOutput )
       
  1797     {
       
  1798     HBufC8* cid( NULL );
       
  1799     CDRMRights* perm( NULL );
       
  1800     RPointerArray< CDRMPermission > rights( 1 );
       
  1801     
       
  1802     TCleanupItem cleanup( DoResetAndDestroy2, &rights );
       
  1803     CleanupStack::PushL( cleanup );
       
  1804     
       
  1805     User::LeaveIfError( aClient.ForwardLockURI( cid ) );
       
  1806     CleanupStack::PushL( cid );
       
  1807     
       
  1808     TRAPD( error, aClient.GetDBEntriesL( *cid, rights ) );
       
  1809     
       
  1810     if ( !error )
       
  1811         {
       
  1812         ConvertPermissionL( perm, *( rights[ 0 ] ), *cid );
       
  1813         // No need to pushl 'perm' into cleanup stack.
       
  1814         }
       
  1815     else if ( error == KErrCANoRights )
       
  1816         {
       
  1817         HBufC8* fl( NULL );
       
  1818         RPointerArray< CDRMRights > rightslist( 1 );
       
  1819         
       
  1820         TCleanupItem cleanup2( DoResetAndDestroy, &rightslist );
       
  1821         CleanupStack::PushL( cleanup2 );
       
  1822         
       
  1823         fl = HBufC8::NewLC( KFLROSize + cid->Length() );
       
  1824         
       
  1825         *fl = KROPart1;
       
  1826         fl->Des().Append( *cid );
       
  1827         fl->Des().Append( KROPart2 );
       
  1828             
       
  1829         User::LeaveIfError( ProcessRightsObject( *fl, rightslist ) );
       
  1830     
       
  1831         CleanupStack::PopAndDestroy(); // fl
       
  1832 
       
  1833         perm = rightslist[ 0 ];
       
  1834         rightslist.Remove( 0 );
       
  1835         
       
  1836         CleanupStack::PopAndDestroy(); // cleanup2
       
  1837         
       
  1838         error = KErrNone;
       
  1839         }
       
  1840         
       
  1841     CleanupStack::PopAndDestroy(); // cid
       
  1842 
       
  1843     if ( !error )
       
  1844         {
       
  1845         // There is something.
       
  1846         if ( aOutput )
       
  1847             {
       
  1848             *aOutput = perm;
       
  1849             }
       
  1850         else
       
  1851             {
       
  1852             delete perm; perm = NULL;
       
  1853             }
       
  1854         }
       
  1855         
       
  1856     CleanupStack::PopAndDestroy(); // cleanup
       
  1857     }
       
  1858 
       
  1859 
       
  1860 HBufC8* CDRMMessageParser::EncryptDCFFieldLC( const TDesC8& aOldHeader )
       
  1861     {
       
  1862     HBufC8* res = NULL;
       
  1863     RDRMRightsClient client;
       
  1864     
       
  1865     User::LeaveIfError( client.Connect() );
       
  1866     CleanupClosePushL( client );
       
  1867 
       
  1868     // Make sure FL rights exists.
       
  1869     EnsureFLRightsExistL( client, NULL );
       
  1870 
       
  1871     User::LeaveIfError( 
       
  1872         client.EncodeRightsIssuerField( aOldHeader, res ) );
       
  1873     
       
  1874     CleanupStack::PopAndDestroy(); // client
       
  1875 
       
  1876     CleanupStack::PushL( res );
       
  1877 
       
  1878     return res;
       
  1879     }
       
  1880     
       
  1881 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1882 
       
  1883 //  End of File