omadrm/drmengine/roap/src/RoapEng.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2002-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:  Roap engine
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include <random.h>
       
    22 
       
    23 #include <DocumentHandler.h>
       
    24 
       
    25 #ifdef RD_MULTIPLE_DRIVE
       
    26 #include  <PathInfo.h>
       
    27 #include  <DriveInfo.h>
       
    28 #else
       
    29 #include  <PathInfo.h>
       
    30 #endif
       
    31 
       
    32 #ifndef __WINS__
       
    33 #include <etelmm.h>
       
    34 #include <mmtsy_names.h>
       
    35 #include <SysUtil.h>
       
    36 #endif
       
    37 
       
    38 #include <flogger.h>
       
    39 #include <x509cert.h>
       
    40 #include <x509CertExt.h>
       
    41 #include <hash.h>
       
    42 #include <utf.h>
       
    43 #include <asn1dec.h>
       
    44 #include <centralrepository.h>
       
    45 #include <e32base.h>  // CleanupResetAndDestroyPushL dependencies
       
    46 
       
    47 #include "cleanupresetanddestroy.h" // CleanupResetAndDestroyPushL
       
    48 #include "DrmRights.h"
       
    49 #include "RoapEng.h"
       
    50 #include "RoapTrigger.h"
       
    51 #include "wbxmlroaptriggerparser.h"
       
    52 #include "RoapResponse.h"
       
    53 #include "RoapMessage.h"
       
    54 #include "RoapParser.h"
       
    55 #include "RoapSigner.h"
       
    56 #include "DeviceHello.h"
       
    57 #include "RIHello.h"
       
    58 #include "RegistrationReq.h"
       
    59 #include "RegistrationResp.h"
       
    60 #include "RightsReq.h"
       
    61 #include "RightsResp.h"
       
    62 #include "JoinDomainReq.h"
       
    63 #include "JoinDomainResp.h"
       
    64 #include "LeaveDomainReq.h"
       
    65 #include "LeaveDomainResp.h"
       
    66 #ifdef RD_DRM_METERING
       
    67 #include "MeteringReportReq.h"
       
    68 #include "MeteringReportResp.h"
       
    69 #endif
       
    70 #include "RoapStorageClient.h"
       
    71 #include "RoapDef.h"
       
    72 #include "RoapLog.h"
       
    73 #include "RoapObserver.h"
       
    74 #include "CmlaCrypto.h"
       
    75 #include "DrmRiContext.h"
       
    76 #include "DrmDomainContext.h"
       
    77 #include "DrmProtectedRoParser.h"
       
    78 #include "DRMClockClient.h"
       
    79 #include "DcfRep.h"
       
    80 #include "dcfentry.h"
       
    81 #include "Base64.h"
       
    82 #include "drmsettingsplugininternalcrkeys.h"
       
    83 
       
    84 
       
    85 #define STUB_C_CLASS_IN_NAMESPACE( n, c ) namespace n { class c: public CBase { private: c(); public: virtual ~c(); }; } n::c::c() {} n::c::~c() {}
       
    86 #define STUB_C_CLASS( c ) class c : public CBase { private: c(); public: virtual ~c(); }; c::c() {} c::~c() {}
       
    87 // This class does not do anything.
       
    88 // It is defined here only to keep binary compatibility,
       
    89 // because of unintentional class name leak in
       
    90 // armv5 export history.
       
    91 // Don't ever use this class for anything.
       
    92 STUB_C_CLASS_IN_NAMESPACE( Roap , CWbxmlRoapTriggerToXmlParser )
       
    93 
       
    94 // Yet another stub classes because of moved classes
       
    95 // which have leaked virtual table entries
       
    96 STUB_C_CLASS( COCSPResponse )
       
    97 STUB_C_CLASS( COCSPResponseCertInfo )
       
    98 
       
    99 
       
   100 using namespace Roap;
       
   101 // ================= CONSTANTS =======================
       
   102 // For parsing multipart content
       
   103 _LIT8(KCmlaIp1, "http://www.cm-la.com/tech/cmlaip/cmlaip#cmlaip-1");
       
   104 _LIT8(KLeaveDomainElement, "leaveDomain");
       
   105 _LIT8(KSignedInfoElement, "SignedInfo");
       
   106 _LIT(KBOM1, "\xFFFE");
       
   107 _LIT(KBOM2, "\xFEFF");
       
   108 #ifdef RD_DRM_METERING
       
   109 _LIT8( KRoapVersion11, "1.1" );
       
   110 #endif
       
   111 
       
   112 static const TInt KDomainGenerationLength( 3 );
       
   113 static const TInt KMinCertChainLength( 3 );
       
   114 // ================= LOCAL FUNCTIONS =======================
       
   115 
       
   116 LOCAL_C TBool SortArrays(
       
   117     RPointerArray<HBufC8>& aKeys,
       
   118     RPointerArray<HBufC8>& aMacs,
       
   119     RPointerArray<HBufC8>& aElements,
       
   120     RArray<TInt>& aOrder )
       
   121     {
       
   122     TInt i;
       
   123     TInt j;
       
   124     TInt index;
       
   125     HBufC8* temp1 = NULL;
       
   126     HBufC8* temp2 = NULL;
       
   127     HBufC8* temp3 = NULL;
       
   128     TBool isInOrder = ETrue;
       
   129 
       
   130     if ( aOrder.Count() != aKeys.Count() || aKeys.Count() != aMacs.Count()
       
   131         || aMacs.Count() != aElements.Count() )
       
   132         {
       
   133         return EFalse;
       
   134         }
       
   135 
       
   136     for ( i = 0; i < aKeys.Count(); i++ )
       
   137         {
       
   138         index = aOrder[i];
       
   139         temp1 = aKeys[i];
       
   140         temp2 = aMacs[i];
       
   141         temp3 = aElements[i];
       
   142         j = i;
       
   143         while ( ( j > 0 ) && ( aOrder[j - 1] > index ) )
       
   144             {
       
   145             isInOrder = EFalse;
       
   146             aOrder[j] = aOrder[j - 1];
       
   147             aKeys[j] = aKeys[j - 1];
       
   148             aMacs[j] = aMacs[j - 1];
       
   149             aElements[j] = aElements[j - 1];
       
   150             j = j - 1;
       
   151             }
       
   152         aOrder[j] = index;
       
   153         aKeys[j] = temp1;
       
   154         aMacs[j] = temp2;
       
   155         aElements[j] = temp3;
       
   156         }
       
   157     return isInOrder;
       
   158     }
       
   159 
       
   160 // ================= MEMBER FUNCTIONS =======================
       
   161 
       
   162 // ---------------------------------------------------------
       
   163 // CRoapEng::NewL()
       
   164 // ---------------------------------------------------------
       
   165 //
       
   166 EXPORT_C CRoapEng* CRoapEng::NewL()
       
   167     {
       
   168     CRoapEng* engine = new ( ELeave ) CRoapEng();
       
   169     CleanupStack::PushL( engine );
       
   170     engine->ConstructL();
       
   171     CleanupStack::Pop( engine );
       
   172     return engine;
       
   173     }
       
   174 
       
   175 // ---------------------------------------------------------
       
   176 // CRoapEng::~CRoapEng()
       
   177 // ---------------------------------------------------------
       
   178 //
       
   179 EXPORT_C CRoapEng::~CRoapEng()
       
   180     {
       
   181     if ( iStorageClient )
       
   182         {
       
   183         iStorageClient->Close();
       
   184         }
       
   185     delete iStorageClient;
       
   186     if ( iClockClient )
       
   187         {
       
   188         iClockClient->Close();
       
   189         }
       
   190     delete iClockClient;
       
   191     delete iParser;
       
   192     delete iSigner;
       
   193     delete iDeviceId;
       
   194     delete iRoParser;
       
   195     delete iDcfRep;
       
   196     iRiAlgorithms.ResetAndDestroy();
       
   197     }
       
   198 
       
   199 // ---------------------------------------------------------
       
   200 // CRoapEng::~CRoapEng()
       
   201 // ---------------------------------------------------------
       
   202 //
       
   203 void CRoapEng::ConstructL()
       
   204     {
       
   205     LOGLIT( "CRoapEng::ConstructL" )
       
   206 
       
   207     CRoapEngBase::ConstructL();
       
   208     iParser = CRoapParser::NewL();
       
   209     iStorageClient = new ( ELeave ) RRoapStorageClient;
       
   210     User::LeaveIfError( iStorageClient->Connect() );
       
   211     iClockClient = new ( ELeave ) RDRMClockClient;
       
   212     User::LeaveIfError( iClockClient->Connect() );
       
   213     TBuf8<SHA1_HASH> deviceId;
       
   214     iStorageClient->GetDevicePublicKeyHashL( deviceId );
       
   215     iDeviceId = deviceId.AllocL();
       
   216     iSigner = CRoapSigner::NewL( *iStorageClient );
       
   217     iRoParser = CDrmProtectedRoParser::NewL();
       
   218     iDcfRep = CDcfRep::NewL();
       
   219     iCertNeeded = ETrue;
       
   220     iRiSupportsCertCaching = EFalse;
       
   221     iTransStatus = ENotAsked;
       
   222     iSelectedAlgorithms = EOma;
       
   223     iSelectedRoot = KNullDesC8;
       
   224     iStorageClient->SelectTrustedRootL( KNullDesC8 );
       
   225     iDeviceTimeError = EFalse;
       
   226     iDomainId.SetLength( 0 );
       
   227     iSecureTime = ETrue;
       
   228     iZone = 0;
       
   229     }
       
   230 
       
   231 // ---------------------------------------------------------
       
   232 // CRoapEng::CRoapEng()
       
   233 // ---------------------------------------------------------
       
   234 //
       
   235 CRoapEng::CRoapEng() :
       
   236     CRoapEngBase()
       
   237     {
       
   238     }
       
   239 
       
   240 // ---------------------------------------------------------
       
   241 // CRoapEng::ParseTriggerL()
       
   242 // ---------------------------------------------------------
       
   243 //
       
   244 CRoapTrigger* CRoapEng::ParseTriggerL( const TDesC8& aTrigger )
       
   245     {
       
   246     LOGLIT( "CRoapEng::ParseTriggerL" )
       
   247 
       
   248     CRoapTrigger* trigger( NULL );
       
   249     RBuf8 xmlTrigger;
       
   250     CleanupClosePushL( xmlTrigger );
       
   251     _LIT8( KRoap, "<roap:roapTrigger" );
       
   252     if ( aTrigger.FindF( KRoap ) == KErrNotFound )
       
   253         {
       
   254         DRM::CWbxmlRoapTriggerParser* wbParser(
       
   255             DRM::CWbxmlRoapTriggerParser::NewLC() );
       
   256         HBufC8* b( NULL );
       
   257         TRAPD( parseError, b = wbParser->ParseL( aTrigger ) );
       
   258         if ( parseError == KErrNone )
       
   259             {
       
   260             xmlTrigger.Assign( b );
       
   261             b = NULL;
       
   262             LOGLIT( "  We have a WBXML trigger" )
       
   263             }
       
   264         else
       
   265             { // OMA BCAST: Check if this is an XML trigger after all..
       
   266             LOGLIT( "  We have an XML trigger after all" )
       
   267             xmlTrigger.CreateL( aTrigger );
       
   268             }
       
   269         CleanupStack::PopAndDestroy( wbParser );
       
   270         }
       
   271     else
       
   272         {
       
   273         xmlTrigger.CreateL( aTrigger );
       
   274         }
       
   275     trigger = iParser->ParseRoapTriggerL( xmlTrigger );
       
   276 
       
   277     CleanupStack::PushL( trigger );
       
   278     if ( !trigger || !trigger->ValidTrigger() )
       
   279         {
       
   280         User::Leave( KErrRoapGeneral );
       
   281         }
       
   282 
       
   283     // check that SilentRightsUrl is on the white list
       
   284     // URL is searched from pre-configured white list
       
   285     TBool fromPreConfiguredWhiteList( ETrue );
       
   286     if ( iStorageClient->WhiteListURLExistsL( *trigger->iRoapUrl, fromPreConfiguredWhiteList ) )
       
   287         {
       
   288         iAllowedToContactRi = ETrue;
       
   289         }
       
   290 
       
   291     if ( trigger->iTriggerType == ELeaveDomainTrigger && trigger->iSignature )
       
   292         {
       
   293         if ( !VerifyTriggerSignatureL( xmlTrigger, *trigger ) )
       
   294             {
       
   295             User::Leave( KErrRoapServerFatal );
       
   296             }
       
   297         }
       
   298 
       
   299     CleanupStack::Pop( trigger );
       
   300     CleanupStack::PopAndDestroy( &xmlTrigger );
       
   301 
       
   302     return trigger;
       
   303     }
       
   304 
       
   305 // ---------------------------------------------------------
       
   306 // CRoapEng::GetRIContextL()
       
   307 // ---------------------------------------------------------
       
   308 //
       
   309 void CRoapEng::GetRIContextL( TBool& aRegistered, const TDesC8& aRiId )
       
   310     {
       
   311     LOGLIT( "CRoapEng::GetRIContextL" )
       
   312 
       
   313     CDRMRIContext* context = NULL;
       
   314 
       
   315     aRegistered = EFalse;
       
   316 
       
   317     // delete old RI context and obtain a new one
       
   318     delete iStoredRiContext;
       
   319     iStoredRiContext = NULL;
       
   320     context = iStorageClient->GetRIContextL( aRiId );
       
   321     if ( !context )
       
   322         {
       
   323         return;
       
   324         }
       
   325 
       
   326     iStoredRiContext = context;
       
   327     iRiSupportsCertCaching = iStoredRiContext->DeviceCertCached();
       
   328     iSelectedRoot = iStoredRiContext->SelectedDeviceRoot();
       
   329     iStorageClient->SelectTrustedRootL( iSelectedRoot );
       
   330 
       
   331     if ( context->CertificateChain().Count() && context->ExpiryTime()
       
   332         > GetDrmTimeL() )
       
   333         {
       
   334         aRegistered = ETrue;
       
   335         iUseRiContextUrl = EFalse;
       
   336         }
       
   337     else
       
   338         {
       
   339         // Received Context was invalid or expired
       
   340         iUseRiContextUrl = EFalse;
       
   341         delete iStoredRiContext;
       
   342         iStoredRiContext = NULL;
       
   343         }
       
   344     }
       
   345 
       
   346 // ---------------------------------------------------------
       
   347 // CRoapEng::GetDomainContextL()
       
   348 // ---------------------------------------------------------
       
   349 //
       
   350 void CRoapEng::GetDomainContextL(
       
   351     TBool& aIsJoined,
       
   352     TBool& aIsValidGeneration,
       
   353     const TDesC8& aDomainId )
       
   354     {
       
   355     LOGLIT( "CRoapEng::GetDomainContextL" )
       
   356 
       
   357     TInt generation = 0;
       
   358     CDRMDomainContext* context = NULL;
       
   359 
       
   360     aIsJoined = EFalse;
       
   361     aIsValidGeneration = EFalse;
       
   362 
       
   363     // last 3 digits are for Domain generation
       
   364     context = iStorageClient->GetDomainContextL( aDomainId );
       
   365 
       
   366     if ( !context )
       
   367         {
       
   368         return;
       
   369         }
       
   370 
       
   371     if ( context->ExpiryTime() > GetDrmTimeL() || context->ExpiryTime()
       
   372         == Time::NullTTime() )
       
   373         {
       
   374         aIsJoined = ETrue;
       
   375         }
       
   376 
       
   377     TLex8 lex( aDomainId.Right( KDomainGenerationLength ) );
       
   378     lex.Val( generation );
       
   379 
       
   380     if ( context->DomainGeneration() >= generation )
       
   381         {
       
   382         aIsValidGeneration = ETrue;
       
   383         }
       
   384 
       
   385     delete context;
       
   386     }
       
   387 
       
   388 // ---------------------------------------------------------
       
   389 // CRoapEng::CreateReqMessageL()
       
   390 // ---------------------------------------------------------
       
   391 //
       
   392 void CRoapEng::CreateReqMessageL()
       
   393     {
       
   394     LOGLIT( "CRoapEng::CreateReqMessageL" )
       
   395 
       
   396     __ASSERT_ALWAYS( iTrigger, User::Invariant() );
       
   397     __ASSERT_ALWAYS( !iRequest, User::Invariant() );
       
   398 
       
   399     switch ( iReqMessage )
       
   400         {
       
   401         case EDeviceHello:
       
   402             {
       
   403             iRequest = CreateDeviceHelloL();
       
   404             break;
       
   405             }
       
   406         case ERegistration:
       
   407             {
       
   408             iRequest = CreateRegistrationRequestL();
       
   409             break;
       
   410             }
       
   411         case EROAcquisition:
       
   412             {
       
   413             iRequest = CreateRightsRequestL();
       
   414             break;
       
   415             }
       
   416         case EJoinDomain:
       
   417             {
       
   418             iRequest = CreateJoinDomainRequestL();
       
   419             break;
       
   420             }
       
   421         case ELeaveDomain:
       
   422             {
       
   423             iRequest = CreateLeaveDomainRequestL();
       
   424             break;
       
   425             }
       
   426 #ifdef RD_DRM_METERING
       
   427         case EMeteringRequest:
       
   428             {
       
   429             iRequest = CreateMeteringReportRequestL();
       
   430             break;
       
   431             }
       
   432 #endif
       
   433         default:
       
   434             {
       
   435             User::Leave( KErrArgument );
       
   436             }
       
   437         }
       
   438     }
       
   439 
       
   440 // ---------------------------------------------------------
       
   441 // CRoapEng::CreateDeviceHelloL()
       
   442 // ---------------------------------------------------------
       
   443 //
       
   444 CRoapMessage* CRoapEng::CreateDeviceHelloL()
       
   445     {
       
   446     LOGLIT( "CRoapEng::CreateDeviceHelloL" )
       
   447     PERFORMANCE_LOGLIT( "Registration protocol started" )
       
   448 
       
   449     RPointerArray<TDesC8> idArray;
       
   450     CDeviceHello* req = CDeviceHello::NewL();
       
   451     CleanupStack::PushL( req );
       
   452 
       
   453     // Multi-PKI addition
       
   454     CleanupResetAndDestroyPushL( idArray );
       
   455     CreateDeviceIdHashArrayL( idArray );
       
   456     for ( TInt i = 0; i < idArray.Count(); i++ )
       
   457         {
       
   458         req->iDeviceIdArray.AppendL( *idArray[i] );
       
   459         }
       
   460     CleanupStack::PopAndDestroy( &idArray );
       
   461     // Multi-PKI
       
   462 
       
   463 #ifndef RD_DRM_METERING
       
   464     req->iVersion.Copy( KRoapVersion ); // Version 1.0
       
   465 #else
       
   466     req->iVersion.Copy( KRoapVersion11 );
       
   467 #endif
       
   468     if ( iTrigger->iNonce )
       
   469         {
       
   470         req->iTriggerNonce = iTrigger->iNonce->AllocL();
       
   471         }
       
   472     CmlaCrypto::SupportedAlgorithmsL( req->iAlgorithms );
       
   473     iSelectedAlgorithms = EOma;
       
   474 
       
   475     CleanupStack::Pop( req );
       
   476     return req;
       
   477     }
       
   478 
       
   479 // ---------------------------------------------------------
       
   480 // CRoapEng::CreateRegistrationRequestL()
       
   481 // ---------------------------------------------------------
       
   482 //
       
   483 CRoapMessage* CRoapEng::CreateRegistrationRequestL()
       
   484     {
       
   485     LOGLIT( "CRoapEng::CreateRegistrationRequestL ->" )
       
   486 
       
   487     __ASSERT_ALWAYS( iResponse, User::Invariant() );
       
   488 
       
   489     CRegistrationReq* req = NULL;
       
   490     CRIHello* resp = NULL;
       
   491     RPointerArray<HBufC8> trustedRootArray;
       
   492     HBufC8* temp = NULL;
       
   493 
       
   494     resp = STATIC_CAST( CRIHello*, iResponse );
       
   495     req = CRegistrationReq::NewL();
       
   496     CleanupStack::PushL( req );
       
   497     if ( resp->iSession )
       
   498         {
       
   499         req->iSession = resp->iSession->AllocL();
       
   500         }
       
   501     else
       
   502         {
       
   503         User::Leave( KErrRoapServerFatal );
       
   504         }
       
   505 
       
   506     req->iNonce.SetLength( KDeviceNonceLength );
       
   507     TRandom::Random( req->iNonce );
       
   508 
       
   509     req->iTime = GetDrmTimeL();
       
   510 
       
   511     // store the nonce for DRM Time sync
       
   512     iRegReqNonce = req->iNonce;
       
   513 
       
   514     if ( iCertNeeded )
       
   515         {
       
   516         req->iCertificateChain = GetCertificateChainL();
       
   517         if ( resp->iCertificateCaching )
       
   518             {
       
   519             iCertNeeded = EFalse;
       
   520             }
       
   521         }
       
   522 
       
   523     // Send all our trusted roots to the RI
       
   524     CleanupResetAndDestroyPushL( trustedRootArray );
       
   525 
       
   526     LOGLIT( "  Getting trusted roots" )
       
   527 
       
   528     iStorageClient->GetTrustedRootsL( trustedRootArray );
       
   529 
       
   530     if ( !trustedRootArray.Count() )
       
   531         {
       
   532         // No trusted roots found!
       
   533         LOGLIT( "  No trusted roots found!" )
       
   534         User::Leave( KErrRoapDevice );
       
   535         }
       
   536     for ( TInt i = 0; i < trustedRootArray.Count(); i++ )
       
   537         {
       
   538         temp = trustedRootArray[i]->AllocLC();
       
   539         req->iTrustedAuthorities.AppendL( temp );
       
   540         CleanupStack::Pop( temp );
       
   541         }
       
   542 
       
   543     LOGLIT( "  Setting server info" )
       
   544     if ( resp->iServerInfo && resp->iServerInfo->Size() )
       
   545         {
       
   546         req->iServerInfo = resp->iServerInfo->AllocL();
       
   547         }
       
   548 
       
   549     if ( iStoredRiContext )
       
   550         {
       
   551         LOGLIT( "  RI context available" )
       
   552         req->iPeerKeyIdentifier = iStoredRiContext->RIID();
       
   553 
       
   554         if ( iStoredRiContext->OCSPResponse().Count() && !iDeviceTimeError )
       
   555             {
       
   556             req->iOcspInfoStored = ETrue;
       
   557             req->iOcspResponderKeyId = GetOCSPResponderKeyHashL();
       
   558             }
       
   559         }
       
   560     if ( resp->iNeedDeviceDetails )
       
   561         {
       
   562         LOGLIT( "  Getting device details" )
       
   563         GetDeviceDetailsL( req->iDeviceDetailsManufacturer,
       
   564             req->iDeviceDetailsModel, req->iDeviceDetailsVersion );
       
   565         }
       
   566 
       
   567     if ( iTrigger->iNonce )
       
   568         {
       
   569         req->iTriggerNonce = iTrigger->iNonce->AllocL();
       
   570         }
       
   571 
       
   572     CleanupStack::PopAndDestroy( &trustedRootArray );
       
   573     CleanupStack::Pop( req );
       
   574 
       
   575     LOGLIT( "CRoapEng::CreateRegistrationRequestL <-" )
       
   576 
       
   577     return req;
       
   578     }
       
   579 
       
   580 // ---------------------------------------------------------
       
   581 // CRoapEng::CreateRightsRequestL()
       
   582 // ---------------------------------------------------------
       
   583 //
       
   584 CRoapMessage* CRoapEng::CreateRightsRequestL()
       
   585     {
       
   586     LOGLIT( "CRoapEng::CreateRightsRequestL" )
       
   587     PERFORMANCE_LOGLIT( "RO acquisition protocol started" )
       
   588 
       
   589     __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
   590 
       
   591     CRightsReq* req = NULL;
       
   592     RPointerArray<HBufC8> ttIDs;
       
   593     RPointerArray<HBufC8> cids;
       
   594     HBufC8* temp = NULL;
       
   595     TBuf8<SHA1_HASH> deviceId;
       
   596 
       
   597     req = CRightsReq::NewL();
       
   598     CleanupStack::PushL( req );
       
   599 
       
   600     req->iNonce.SetLength( KDeviceNonceLength );
       
   601     TRandom::Random( req->iNonce );
       
   602 
       
   603     req->iTime = GetDrmTimeL();
       
   604 
       
   605     iStorageClient->GetDevicePublicKeyHashL( deviceId );
       
   606     delete iDeviceId;
       
   607     iDeviceId = NULL;
       
   608     iDeviceId = deviceId.AllocL();
       
   609     req->iDeviceId = *iDeviceId;
       
   610 
       
   611     req->iRiId.Copy( iTrigger->iRiId );
       
   612 
       
   613     if ( !iRiSupportsCertCaching )
       
   614         {
       
   615         req->iCertificateChain = GetCertificateChainL();
       
   616         }
       
   617     if ( iTrigger->iDomainId )
       
   618         {
       
   619         req->iDomainId = iTrigger->iDomainId->AllocL();
       
   620         }
       
   621 
       
   622     for ( TInt i = 0; i < iTrigger->iRoIdList.Count(); i++ )
       
   623         {
       
   624         temp = iTrigger->iRoIdList[i]->AllocLC();
       
   625         req->iRoIdList.AppendL( temp );
       
   626         CleanupStack::Pop( temp );
       
   627         }
       
   628 
       
   629     if ( iStoredRiContext )
       
   630         {
       
   631         req->iPeerKeyIdentifier = iStoredRiContext->RIID();
       
   632 
       
   633         if ( iStoredRiContext->OCSPResponse().Count() )
       
   634             {
       
   635             req->iOcspInfoStored = ETrue;
       
   636             req->iOcspResponderKeyId = GetOCSPResponderKeyHashL();
       
   637             }
       
   638         }
       
   639 
       
   640     CleanupResetAndDestroyPushL( cids );
       
   641 
       
   642     CleanupResetAndDestroyPushL( ttIDs );
       
   643 
       
   644     FetchTransactionIDL( ttIDs, cids );
       
   645 
       
   646     for ( TInt i = 0; i < ttIDs.Count() && i < cids.Count(); i++ )
       
   647         {
       
   648         temp = ttIDs[i]->AllocLC();
       
   649         req->iTransTrackIDs.AppendL( temp );
       
   650         CleanupStack::Pop( temp );
       
   651         temp = cids[i]->AllocLC();
       
   652         req->iContentIDs.AppendL( temp );
       
   653         CleanupStack::Pop( temp );
       
   654         }
       
   655 
       
   656     CleanupStack::PopAndDestroy( &ttIDs );
       
   657     CleanupStack::PopAndDestroy( &cids );
       
   658 
       
   659     if ( iTrigger->iNonce )
       
   660         {
       
   661         req->iTriggerNonce = iTrigger->iNonce->AllocL();
       
   662         }
       
   663 
       
   664     CleanupStack::Pop( req );
       
   665     return req;
       
   666     }
       
   667 
       
   668 // ---------------------------------------------------------
       
   669 // CRoapEng::CreateJoinDomainRequestL()
       
   670 // ---------------------------------------------------------
       
   671 //
       
   672 CRoapMessage* CRoapEng::CreateJoinDomainRequestL()
       
   673     {
       
   674     LOGLIT( "CRoapEng::CreateJoinDomainRequestL" )
       
   675     PERFORMANCE_LOGLIT( "Join domain protocol started" )
       
   676 
       
   677     __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
   678 
       
   679     CJoinDomainReq* req = NULL;
       
   680     TBuf8<SHA1_HASH> deviceId;
       
   681 
       
   682     req = CJoinDomainReq::NewL();
       
   683     CleanupStack::PushL( req );
       
   684 
       
   685     req->iNonce.SetLength( KDeviceNonceLength );
       
   686     TRandom::Random( req->iNonce );
       
   687 
       
   688     req->iTime = GetDrmTimeL();
       
   689 
       
   690     iStorageClient->GetDevicePublicKeyHashL( deviceId );
       
   691     delete iDeviceId;
       
   692     iDeviceId = NULL;
       
   693     iDeviceId = deviceId.AllocL();
       
   694     req->iDeviceId = *iDeviceId;
       
   695 
       
   696     req->iRiId.Copy( iTrigger->iRiId );
       
   697 
       
   698     if ( !iRiSupportsCertCaching )
       
   699         {
       
   700         req->iCertificateChain = GetCertificateChainL();
       
   701         }
       
   702     if ( iTrigger->iDomainId )
       
   703         {
       
   704         req->iDomainId = iTrigger->iDomainId->AllocL();
       
   705         iDomainId.Copy( *req->iDomainId );
       
   706         }
       
   707     else if ( iDomainId.Length() && iTrigger->iTriggerType
       
   708         == ERoAcquisitionTrigger )
       
   709         {
       
   710         req->iDomainId = iDomainId.AllocL();
       
   711         }
       
   712     else
       
   713         {
       
   714         User::Leave( KErrRoapServerFatal );
       
   715         }
       
   716 
       
   717     if ( iStoredRiContext )
       
   718         {
       
   719         req->iPeerKeyIdentifier = iStoredRiContext->RIID();
       
   720 
       
   721         if ( iStoredRiContext->OCSPResponse().Count() )
       
   722             {
       
   723             req->iOcspInfoStored = ETrue;
       
   724             req->iOcspResponderKeyId = GetOCSPResponderKeyHashL();
       
   725             }
       
   726         }
       
   727 
       
   728 #ifdef _DISABLE_HASH_CHAIN_GENERATION
       
   729     req->iHashChainSupport = EFalse;
       
   730 #endif
       
   731 
       
   732     if ( iTrigger->iNonce )
       
   733         {
       
   734         req->iTriggerNonce = iTrigger->iNonce->AllocL();
       
   735         }
       
   736 
       
   737     CleanupStack::Pop( req );
       
   738     return req;
       
   739     }
       
   740 
       
   741 // ---------------------------------------------------------
       
   742 // CRoapEng::CreateLeaveDomainRequestL()
       
   743 // ---------------------------------------------------------
       
   744 //
       
   745 CRoapMessage* CRoapEng::CreateLeaveDomainRequestL()
       
   746     {
       
   747     LOGLIT( "CRoapEng::CreateLeaveDomainRequestL" )
       
   748     PERFORMANCE_LOGLIT( "Leave domain protocol started" )
       
   749 
       
   750     __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
   751 
       
   752     if ( !iTrigger->iDomainId )
       
   753         {
       
   754         User::Leave( KErrRoapServerFatal );
       
   755         }
       
   756     // delete Domain context before sending LeaveDomain req
       
   757     TRAPD( ret, iStorageClient->DeleteDomainContextL( *iTrigger->iDomainId ));
       
   758 
       
   759     CLeaveDomainReq* req = NULL;
       
   760     TBuf8<SHA1_HASH> deviceId;
       
   761 
       
   762     req = CLeaveDomainReq::NewL();
       
   763     CleanupStack::PushL( req );
       
   764 
       
   765     if ( ret == KErrNotFound )
       
   766         {
       
   767         req->iNotMember = ETrue;
       
   768         }
       
   769     else
       
   770         {
       
   771         req->iNotMember = EFalse;
       
   772         User::LeaveIfError( ret );
       
   773         }
       
   774 
       
   775     req->iNonce.SetLength( KDeviceNonceLength );
       
   776     TRandom::Random( req->iNonce );
       
   777 
       
   778     req->iTime = GetDrmTimeL();
       
   779 
       
   780     iStorageClient->GetDevicePublicKeyHashL( deviceId );
       
   781     delete iDeviceId;
       
   782     iDeviceId = NULL;
       
   783     iDeviceId = deviceId.AllocL();
       
   784     req->iDeviceId = *iDeviceId;
       
   785 
       
   786     req->iRiId.Copy( iTrigger->iRiId );
       
   787 
       
   788     if ( !iRiSupportsCertCaching )
       
   789         {
       
   790         req->iCertificateChain = GetCertificateChainL();
       
   791         }
       
   792     if ( iTrigger->iDomainId )
       
   793         {
       
   794         req->iDomainId = iTrigger->iDomainId->AllocL();
       
   795         }
       
   796 
       
   797     if ( iTrigger->iNonce )
       
   798         {
       
   799         req->iTriggerNonce = iTrigger->iNonce->AllocL();
       
   800         }
       
   801 
       
   802     CleanupStack::Pop( req );
       
   803     return req;
       
   804     }
       
   805 // ---------------------------------------------------------
       
   806 // CRoapEng::CreateMeteringReportRequestL()
       
   807 // ---------------------------------------------------------
       
   808 //
       
   809 CRoapMessage* CRoapEng::CreateMeteringReportRequestL()
       
   810     {
       
   811 #ifndef RD_DRM_METERING
       
   812     return NULL;
       
   813 #else
       
   814 
       
   815     LOGLIT( "CRoapEng::CreateMeteringReportRequestL" )
       
   816     PERFORMANCE_LOGLIT( "Metering report creation started" )
       
   817 
       
   818     CMeteringReportReq* req = NULL;
       
   819     TBuf8<SHA1_HASH> deviceId;
       
   820     TBuf8<OmaCrypto::KMacSize> macKey;
       
   821     TBool registered( EFalse );
       
   822 
       
   823     req = CMeteringReportReq::NewL();
       
   824     CleanupStack::PushL( req );
       
   825     req->iAlgorithmInUse = iSelectedAlgorithms;
       
   826     // check if we are not using OMA algorithms
       
   827     // and update selected algorithm accordingly
       
   828     GetRIContextL( registered, iTrigger->iRiId );
       
   829     if ( registered && iStoredRiContext )
       
   830         {
       
   831         for ( TInt i = 0; i < iStoredRiContext->Algorithms().Count(); i++ )
       
   832             {
       
   833             if ( iStoredRiContext->Algorithms()[i]->CompareF( KCmlaIp1() )
       
   834                 == KErrNone )
       
   835                 {
       
   836                 // note currently assumed that only
       
   837                 // 1 of 7 ppossible algorithms used
       
   838                 req->iAlgorithmInUse = ECmlaIp1;
       
   839                 break;
       
   840                 }
       
   841             }
       
   842         }
       
   843 
       
   844     // generate DeviceNonce
       
   845     req->iNonce.SetLength( KDeviceNonceLength );
       
   846     TRandom::Random( req->iNonce );
       
   847 
       
   848     // generate MeteringNonce
       
   849     req->iReportNonce.SetLength( KDeviceNonceLength );
       
   850     TRandom::Random( req->iReportNonce );
       
   851 
       
   852     // fetch secure time for request
       
   853     req->iTime = GetDrmTimeL();
       
   854 
       
   855     // insert DeviceId
       
   856     iStorageClient->GetDevicePublicKeyHashL( deviceId );
       
   857     delete iDeviceId;
       
   858     iDeviceId = NULL;
       
   859     iDeviceId = deviceId.AllocL();
       
   860     req->iDeviceId = *iDeviceId;
       
   861 
       
   862     // insert RiId
       
   863     req->iRiId.Copy( iTrigger->iRiId );
       
   864 
       
   865     // insert Certificate chain if needed
       
   866     if ( !iRiSupportsCertCaching )
       
   867         {
       
   868         req->iCertificateChain = GetCertificateChainL();
       
   869         }
       
   870 
       
   871     // add trigger Nonce
       
   872     if ( iTrigger->iNonce )
       
   873         {
       
   874         req->iTriggerNonce = iTrigger->iNonce->AllocL();
       
   875         }
       
   876 
       
   877     // Get from server encrypted metering report mac key as plain,
       
   878     // MEK and MAC key as encypted, and hash of
       
   879     // PKI public key used in encryition
       
   880     req->iCipherValue = iStorageClient->GetMeteringDataL( req->iRiId, macKey,
       
   881         req->iEncKeyHash, req->iEncryptedMekAndMak );
       
   882 
       
   883     // calculate mac over <encryptedMeteringReport>
       
   884     req->InsertMacL( macKey );
       
   885 
       
   886     CleanupStack::Pop( req );
       
   887     return req;
       
   888 
       
   889 #endif //RD_DRM_METERING
       
   890     }
       
   891 
       
   892 // ---------------------------------------------------------
       
   893 // CRoapEng::HandleRoapResponseL()
       
   894 // ---------------------------------------------------------
       
   895 //
       
   896 void CRoapEng::HandleRoapResponseL( const TDesC8& aXmlResponse )
       
   897     {
       
   898     LOGLIT( "CRoapEng::HandleRoapMessageL" )
       
   899 
       
   900     delete iResponse;
       
   901     iResponse = NULL;
       
   902 
       
   903     switch ( iReqMessage )
       
   904         {
       
   905         case EDeviceHello:
       
   906             {
       
   907             HandleRIHelloPduL( aXmlResponse );
       
   908             break;
       
   909             }
       
   910         case ERegistration:
       
   911             {
       
   912             HandleReqResponsePduL( aXmlResponse );
       
   913             break;
       
   914             }
       
   915         case EROAcquisition:
       
   916             {
       
   917             HandleRightsResponsePduL( aXmlResponse, EFalse );
       
   918             break;
       
   919             }
       
   920         case EJoinDomain:
       
   921             {
       
   922             HandleJoinDomainResponsePduL( aXmlResponse );
       
   923             break;
       
   924             }
       
   925         case ELeaveDomain:
       
   926             {
       
   927             HandleLeaveDomainResponsePduL( aXmlResponse );
       
   928             break;
       
   929             }
       
   930 #ifdef RD_DRM_METERING
       
   931         case EMeteringRequest:
       
   932             {
       
   933             HandleMeteringReportResponsePduL( aXmlResponse );
       
   934             break;
       
   935             }
       
   936 #endif
       
   937         default:
       
   938             {
       
   939             User::Leave( KErrArgument );
       
   940             }
       
   941         }
       
   942     }
       
   943 
       
   944 // ---------------------------------------------------------
       
   945 // CRoapEng::HandleRIHelloPduL()
       
   946 // ---------------------------------------------------------
       
   947 //
       
   948 void CRoapEng::HandleRIHelloPduL( const TDesC8& aRiHello )
       
   949     {
       
   950     LOGLIT( "CRoapEng::HandleRIHelloPduL" )
       
   951 
       
   952     CRIHello* resp = NULL;
       
   953     HBufC8* temp = NULL;
       
   954 
       
   955     resp = iParser->ParseRIHelloL( aRiHello );
       
   956     iRoapStatus = resp->iStatus;
       
   957     iResponse = resp;
       
   958     if ( iRoapStatus == ESuccess )
       
   959         {
       
   960         iCertNeeded = ETrue;
       
   961         iRiSupportsCertCaching = EFalse;
       
   962 
       
   963         if ( resp->iPeerKeyIdentifier )
       
   964             {
       
   965             iRiSupportsCertCaching = ETrue;
       
   966             if ( resp->iPeerKeyId.Length() )
       
   967                 {
       
   968                 if ( resp->iPeerKeyId.CompareF( *iDeviceId ) == KErrNone )
       
   969                     {
       
   970                     iCertNeeded = EFalse;
       
   971                     }
       
   972                 }
       
   973             else
       
   974                 {
       
   975                 iCertNeeded = EFalse;
       
   976                 }
       
   977             }
       
   978         else if ( resp->iCertificateCaching )
       
   979             {
       
   980             iRiSupportsCertCaching = ETrue;
       
   981             }
       
   982 
       
   983         if ( resp->iAlgorithms.Count() )
       
   984             {
       
   985             iRiAlgorithms.ResetAndDestroy();
       
   986             for ( TInt i = 0; i < resp->iAlgorithms.Count(); i++ )
       
   987                 {
       
   988                 if ( resp->iAlgorithms[i]->CompareF( KCmlaIp1() ) == KErrNone )
       
   989                     {
       
   990                     iSelectedAlgorithms = ECmlaIp1;
       
   991                     }
       
   992                 temp = resp->iAlgorithms[i]->AllocLC();
       
   993                 iRiAlgorithms.AppendL( temp );
       
   994                 CleanupStack::Pop( temp );
       
   995                 }
       
   996             }
       
   997         iRiId.Copy( resp->iRiId );
       
   998         iRiVersion.Copy( resp->iSelectedVersion );
       
   999 
       
  1000         /***
       
  1001          This is needed when the multiple PKIs are supported.
       
  1002          ***/
       
  1003         if ( resp->iTrustedAuthorities.Count() )
       
  1004             {
       
  1005             // select the first matching root from the list
       
  1006             LOGLIT( "Choose the first matching trust anchor" )
       
  1007             iStorageClient->SelectTrustedRootL( resp->iTrustedAuthorities,
       
  1008                 iSelectedRoot );
       
  1009             LOGLIT( "The trust anchor selected" )
       
  1010             DETAILLOGHEX( iSelectedRoot.Ptr(), iSelectedRoot.Length() )
       
  1011             }
       
  1012         else
       
  1013             {
       
  1014             if ( iStoredRiContext && iStoredRiContext->RIID() == iRiId )
       
  1015                 {
       
  1016                 if ( iSelectedRoot != iStoredRiContext->SelectedDeviceRoot() )
       
  1017                     {
       
  1018                     DETAILLOGLIT( "Changing trusted root to that of saved RI context" )
       
  1019                     DETAILLOGLIT( "old root" )
       
  1020                     DETAILLOGHEX( iSelectedRoot.Ptr(), iSelectedRoot.Length() )
       
  1021 
       
  1022                     iSelectedRoot = iStoredRiContext->SelectedDeviceRoot();
       
  1023                     iStorageClient->SelectTrustedRootL( iSelectedRoot );
       
  1024                     }
       
  1025                 DETAILLOGLIT( "Using trusted root of saved RI context" )
       
  1026                 DETAILLOGHEX( iSelectedRoot.Ptr(), iSelectedRoot.Length() )
       
  1027                 }
       
  1028             else
       
  1029                 {
       
  1030                 DETAILLOGLIT( "Using default trusted root" )
       
  1031                 iSelectedRoot = KNullDesC8;
       
  1032                 iStorageClient->SelectTrustedRootL( iSelectedRoot );
       
  1033                 }
       
  1034             }
       
  1035 
       
  1036         iSigner->AddRequestL( aRiHello );
       
  1037         }
       
  1038     else if ( resp->iErrorUrl )
       
  1039         {
       
  1040         if ( iObserver )
       
  1041             {
       
  1042             iObserver->ErrorUrlL( *resp->iErrorUrl );
       
  1043             }
       
  1044         }
       
  1045     }
       
  1046 
       
  1047 // ---------------------------------------------------------
       
  1048 // CRoapEng::HandleReqResponsePduL()
       
  1049 // ---------------------------------------------------------
       
  1050 //
       
  1051 void CRoapEng::HandleReqResponsePduL( const TDesC8& aRegResp )
       
  1052     {
       
  1053     LOGLIT( "CRoapEng::HandleReqResponsePduL" )
       
  1054 
       
  1055     CRegistrationResp* resp = NULL;
       
  1056     CDRMRIContext* context = NULL;
       
  1057     CX509Certificate* cert = NULL;
       
  1058     TTime riExpiry;
       
  1059     TBool status = EFalse;
       
  1060     TUint8 riCertCaching = EFalse;
       
  1061 
       
  1062     resp = iParser->ParseRegistrationRespL( aRegResp );
       
  1063     iRoapStatus = resp->iStatus;
       
  1064     iResponse = resp;
       
  1065     if ( iRoapStatus == ESuccess )
       
  1066         {
       
  1067         if ( resp->iOcspResponse.Count() > 0 )
       
  1068             {
       
  1069             // adjust DRM Time according to OCSP response
       
  1070             // All needed verifications done in server side
       
  1071             TBool deviceTimeUpdated( EFalse );
       
  1072             if ( resp->iCertificateChain.Count() > 0 )
       
  1073                 {
       
  1074                 deviceTimeUpdated = iStorageClient->UpdateDrmTimeL(
       
  1075                     resp->iCertificateChain, resp->iOcspResponse,
       
  1076                     iRegReqNonce );
       
  1077                 }
       
  1078             else if ( iStoredRiContext )
       
  1079                 {
       
  1080                 deviceTimeUpdated = iStorageClient->UpdateDrmTimeL(
       
  1081                     iStoredRiContext->CertificateChain(),
       
  1082                     resp->iOcspResponse, iRegReqNonce );
       
  1083                 }
       
  1084             if ( deviceTimeUpdated )
       
  1085                 {
       
  1086                 LOGLIT( "drm time updated" )
       
  1087                 iDeviceTimeError = EFalse;
       
  1088                 }
       
  1089             }
       
  1090 
       
  1091         if ( !iStoredRiContext || ( resp->iCertificateChain.Count()
       
  1092             && resp->iOcspResponse.Count() ) )
       
  1093             {
       
  1094             status = VerifyCertificateChainL( resp->iCertificateChain,
       
  1095                 resp->iOcspResponse );
       
  1096             if ( !status )
       
  1097                 {
       
  1098                 LOGLIT( "Certificate chain validation failed" )
       
  1099                 User::Leave( KErrRoapServerFatal );
       
  1100                 }
       
  1101             status = ValidateRiIdL( iRiId, *resp->iCertificateChain[0] );
       
  1102             if ( !status )
       
  1103                 {
       
  1104                 LOGLIT( "RI ID validation failed" )
       
  1105                 User::Leave( KErrRoapServerFatal );
       
  1106                 }
       
  1107             }
       
  1108 
       
  1109         if ( iStoredRiContext )
       
  1110             {
       
  1111             // if we have already stored certificates -> use those.
       
  1112             status = VerifySignatureL( aRegResp, *resp->iSignature,
       
  1113                 iStoredRiContext->CertificateChain() );
       
  1114             }
       
  1115         else
       
  1116             {
       
  1117             // otherwise use the received certificates
       
  1118             status = VerifySignatureL( aRegResp, *resp->iSignature,
       
  1119                 resp->iCertificateChain );
       
  1120             }
       
  1121 
       
  1122         if ( !status )
       
  1123             {
       
  1124             LOGLIT( "Signature verification failed" )
       
  1125             User::Leave( KErrRoapServerFatal );
       
  1126             }
       
  1127 
       
  1128         if ( resp->iCertificateChain.Count() )
       
  1129             {
       
  1130             // Validate RI certificate
       
  1131             cert = CX509Certificate::NewLC( *resp->iCertificateChain[0] );
       
  1132 
       
  1133             status = ValidateRiCertificateL( cert );
       
  1134             if ( !status )
       
  1135                 {
       
  1136                 User::LeaveIfError( KErrRoapServerFatal );
       
  1137                 }
       
  1138 
       
  1139             riExpiry = cert->ValidityPeriod().Finish();
       
  1140 
       
  1141             iRiSupportsCertCaching ? riCertCaching = ETrue : riCertCaching
       
  1142                 = EFalse;
       
  1143 
       
  1144             context = CDRMRIContext::NewLC( iRiId, *iRiAlias, iRiVersion,
       
  1145                 iRiAlgorithms, resp->iWhiteList, *resp->iRiUrl, riExpiry,
       
  1146                 resp->iCertificateChain, resp->iOcspResponse, riCertCaching,
       
  1147                 iSelectedRoot, ETrue );
       
  1148 
       
  1149             iStorageClient->AddRIContextL( *context );
       
  1150             delete iStoredRiContext;
       
  1151             iStoredRiContext = context;
       
  1152             CleanupStack::Pop( context );
       
  1153             CleanupStack::PopAndDestroy( cert );
       
  1154             }
       
  1155         }
       
  1156     else
       
  1157         {
       
  1158         if ( resp->iErrorUrl )
       
  1159             {
       
  1160             if ( iObserver )
       
  1161                 {
       
  1162                 iObserver->ErrorUrlL( *resp->iErrorUrl );
       
  1163                 }
       
  1164             }
       
  1165         iSigner->ResetResponses();
       
  1166         }
       
  1167 
       
  1168     PERFORMANCE_LOGLIT( "Registration protocol completed" )
       
  1169     }
       
  1170 
       
  1171 // ---------------------------------------------------------
       
  1172 // CRoapEng::HandleRightsResponseL()
       
  1173 // ---------------------------------------------------------
       
  1174 //
       
  1175 void CRoapEng::HandleRightsResponsePduL(
       
  1176     const TDesC8& aRightsResp,
       
  1177     TBool aOnePass )
       
  1178     {
       
  1179     LOGLIT( "CRoapEng::HandleRightsResponsePduL" )
       
  1180 
       
  1181     CRightsResp* resp = NULL;
       
  1182     TBool status = EFalse;
       
  1183 
       
  1184     resp = iParser->ParseRightsRespL( aRightsResp );
       
  1185 
       
  1186     CleanupStack::PushL( resp );
       
  1187 
       
  1188     if ( resp->iStatus == ESuccess )
       
  1189         {
       
  1190         if ( !aOnePass )
       
  1191             {
       
  1192             // 2-pass protocol
       
  1193             __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
  1194 
       
  1195             CRightsReq* request = NULL;
       
  1196             request = STATIC_CAST( CRightsReq*, iRequest );
       
  1197             if ( resp->iDeviceId.CompareF( request->iDeviceId ) != KErrNone
       
  1198                 || resp->iRiId.CompareF( request->iRiId ) != KErrNone
       
  1199                 || resp->iNonce->CompareF( request->iNonce ) != KErrNone )
       
  1200                 {
       
  1201                 User::Leave( KErrRoapServerFatal );
       
  1202                 }
       
  1203             }
       
  1204         else
       
  1205             {
       
  1206             LOGLIT( "1-pass ROAP" )
       
  1207             // 1-pass protocol
       
  1208             TBool registered = EFalse;
       
  1209             GetRIContextL( registered, resp->iRiId );
       
  1210             if ( !registered )
       
  1211                 {
       
  1212                 // Recoverable error by re-registering the device
       
  1213                 // (after receiving user consent or iv device belongs to whiteliust)
       
  1214                 LOGLIT( "Device not registered to RI" )
       
  1215                 User::Leave( KErrRoapNotRegistered );
       
  1216                 }
       
  1217             if ( resp->iDeviceId.CompareF( *iDeviceId ) != KErrNone )
       
  1218                 {
       
  1219                 // Unrecoverable error
       
  1220                 LOGLIT( "Device ID mismatch!" )
       
  1221                 User::Leave( KErrRoapServerFatal );
       
  1222                 }
       
  1223             }
       
  1224 
       
  1225         if ( !iStoredRiContext || ( resp->iCertificateChain.Count()
       
  1226             && resp->iOcspResponse.Count() ) )
       
  1227             {
       
  1228             status = VerifyCertificateChainL( resp->iCertificateChain,
       
  1229                 resp->iOcspResponse );
       
  1230             if ( !status )
       
  1231                 {
       
  1232                 LOGLIT( "Certificate chain validation failed" )
       
  1233                 User::Leave( KErrRoapServerFatal );
       
  1234                 }
       
  1235             status = ValidateRiIdL( resp->iRiId, *resp->iCertificateChain[0] );
       
  1236             if ( !status )
       
  1237                 {
       
  1238                 LOGLIT( "RI ID validation failed" )
       
  1239                 User::Leave( KErrRoapServerFatal );
       
  1240                 }
       
  1241             }
       
  1242 
       
  1243         status = VerifySignatureL( aRightsResp, *resp->iSignature,
       
  1244             iStoredRiContext->CertificateChain() );
       
  1245         if ( !status )
       
  1246             {
       
  1247             LOGLIT( "Signature verification failed" )
       
  1248             User::Leave( KErrRoapServerFatal );
       
  1249             }
       
  1250 
       
  1251         iReturnedROs.ResetAndDestroy();
       
  1252         TRAPD( r, iRoParser->ParseAndStoreL( aRightsResp, iReturnedROs ));
       
  1253 
       
  1254         if ( r == KErrRightsServerDomainNotRegistered )
       
  1255             {
       
  1256             // perform implicit Join Domain
       
  1257             LOGLIT( "Domain RO received - Not joined" )
       
  1258             LOGLIT( "Perform impicit Join Domain before storing the RO" )
       
  1259 
       
  1260             HBufC8* domainID = NULL;
       
  1261 
       
  1262             domainID = iRoParser->GetDomainIdL( aRightsResp );
       
  1263 
       
  1264             if ( domainID && domainID->Length() <= KDomainIdLength )
       
  1265                 {
       
  1266                 iDomainId.Copy( *domainID );
       
  1267                 delete domainID;
       
  1268                 domainID = NULL;
       
  1269                 }
       
  1270             else
       
  1271                 {
       
  1272                 LOGLIT( "No Domain ID available!" )
       
  1273                 User::Leave( KErrRoapServerFatal );
       
  1274                 }
       
  1275 
       
  1276             delete iDomainRightsResp;
       
  1277             iDomainRightsResp = NULL;
       
  1278             iDomainRightsResp = aRightsResp.AllocL();
       
  1279             iImplicitJoinDomain = ETrue;
       
  1280             }
       
  1281         else
       
  1282             {
       
  1283             User::LeaveIfError( r );
       
  1284 
       
  1285             if ( !aOnePass )
       
  1286                 {
       
  1287                 if ( iObserver )
       
  1288                     {
       
  1289                     iObserver->RightsObjectDetailsL( iReturnedROs ); // pass RO details to UI
       
  1290                     }
       
  1291                 }
       
  1292             }
       
  1293 
       
  1294             TRAP( r, InsertTransactionIDL( resp->iTransTrackIDs, resp->iContentIDs ) );
       
  1295             TRAP( r, InsertDomainRosL() );
       
  1296 
       
  1297         // Device DRM Time is insecure, but server thinks that the time is correct
       
  1298         // -> Set DRM Time as secure
       
  1299         if ( !iSecureTime )
       
  1300             {
       
  1301             SetDrmTimeSecureL();
       
  1302             }
       
  1303         }
       
  1304     else
       
  1305         {
       
  1306         if ( resp->iErrorUrl )
       
  1307             {
       
  1308             if ( iObserver )
       
  1309                 {
       
  1310                 iObserver->ErrorUrlL( *resp->iErrorUrl );
       
  1311                 }
       
  1312             }
       
  1313         iSigner->ResetResponses();
       
  1314         }
       
  1315 
       
  1316     CleanupStack::Pop( resp );
       
  1317 
       
  1318     if ( !aOnePass )
       
  1319         {
       
  1320         iRoapStatus = resp->iStatus;
       
  1321         iResponse = resp;
       
  1322         }
       
  1323 
       
  1324     PERFORMANCE_LOGLIT( "RO acquisition protocol completed" )
       
  1325     }
       
  1326 
       
  1327 // ---------------------------------------------------------
       
  1328 // CRoapEng::HandleJoinDomainResponseL()
       
  1329 // ---------------------------------------------------------
       
  1330 //
       
  1331 void CRoapEng::HandleJoinDomainResponsePduL( const TDesC8& aJoinResp )
       
  1332     {
       
  1333     LOGLIT( "CRoapEng::HandleJoinDomainResponsePduL" )
       
  1334 
       
  1335     __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
  1336 
       
  1337     CJoinDomainResp* resp = NULL;
       
  1338     CDRMDomainContext* context = NULL;
       
  1339     RPointerArray<HBufC8> domainKeyElements;
       
  1340     TBool status = EFalse;
       
  1341 
       
  1342     CleanupResetAndDestroyPushL( domainKeyElements );
       
  1343 
       
  1344     resp = iParser->ParseJoinDomainRespL( aJoinResp, domainKeyElements );
       
  1345 
       
  1346     iResponse = resp;
       
  1347     iRoapStatus = resp->iStatus;
       
  1348 
       
  1349     if ( iRoapStatus == ESuccess )
       
  1350         {
       
  1351         if ( resp->iDomainKeyRiId != resp->iRiId )
       
  1352             {
       
  1353             LOGLIT( "resp->iDomainKeyRiId != resp->iRiId" )
       
  1354             User::Leave( KErrRoapServerFatal );
       
  1355             }
       
  1356 
       
  1357         if ( !iStoredRiContext || ( resp->iCertificateChain.Count()
       
  1358             && resp->iOcspResponse.Count() ) )
       
  1359             {
       
  1360             status = VerifyCertificateChainL( resp->iCertificateChain,
       
  1361                 resp->iOcspResponse );
       
  1362             if ( !status )
       
  1363                 {
       
  1364                 LOGLIT( "Certificate chain validation failed" )
       
  1365                 User::Leave( KErrRoapServerFatal );
       
  1366                 }
       
  1367             status = ValidateRiIdL( resp->iRiId, *resp->iCertificateChain[0] );
       
  1368             if ( !status )
       
  1369                 {
       
  1370                 LOGLIT( "RI ID validation failed" )
       
  1371                 User::Leave( KErrRoapServerFatal );
       
  1372                 }
       
  1373             }
       
  1374 
       
  1375         status = VerifySignatureL( aJoinResp, *resp->iSignature,
       
  1376             iStoredRiContext->CertificateChain() );
       
  1377         if ( !status )
       
  1378             {
       
  1379             LOGLIT( "Signature verification failed" )
       
  1380             User::Leave( KErrRoapServerFatal );
       
  1381             }
       
  1382 
       
  1383         if ( resp->iDomainKeys.Count() > 1 && resp->iDomainKeyIDs.Count() > 1
       
  1384             && resp->iDomainKeys.Count() == resp->iDomainKeyIDs.Count() )
       
  1385             {
       
  1386             // Sort domain keys by generation (000 generation is first)
       
  1387             TLex8 lex;
       
  1388             TInt generation = 0;
       
  1389             RArray<TInt> generations;
       
  1390             CleanupClosePushL( generations );
       
  1391 
       
  1392             for ( TInt i = 0; i < resp->iDomainKeyIDs.Count(); i++ )
       
  1393                 {
       
  1394                 lex = resp->iDomainKeyIDs[i]->Right( KDomainGenerationLength );
       
  1395                 lex.Val( generation );
       
  1396                 generations.AppendL( generation );
       
  1397                 }
       
  1398 
       
  1399             SortArrays( resp->iDomainKeys, resp->iMacs, domainKeyElements,
       
  1400                 generations );
       
  1401 
       
  1402             CleanupStack::PopAndDestroy( &generations );
       
  1403             }
       
  1404 
       
  1405         if ( !resp->iDomainKeys.Count() )
       
  1406             {
       
  1407             LOGLIT( "No valid domain keys present!" )
       
  1408             User::Leave( KErrRoapServerFatal );
       
  1409             }
       
  1410 
       
  1411 #ifdef _DISABLE_HASH_CHAIN_GENERATION
       
  1412         resp->iHashChainSupport = EFalse;
       
  1413 #endif
       
  1414 
       
  1415         if ( resp->iHashChainSupport )
       
  1416             {
       
  1417             if ( resp->iDomainKeys.Count() > 1 )
       
  1418                 {
       
  1419                 LOGLIT( "More than one Domain key present, hash chain key generation is supported!" )
       
  1420                 // Might be KErrRoapServerFatal server error
       
  1421                 }
       
  1422             }
       
  1423 
       
  1424         context = CDRMDomainContext::NewLC( iDomainId,
       
  1425             resp->iDomainExpiration, resp->iHashChainSupport,
       
  1426             resp->iDomainKeys, resp->iRiId,
       
  1427             iStoredRiContext->RightsIssuerURL() );
       
  1428         iStorageClient->AddDomainContextL( *context, resp->iMacs,
       
  1429             domainKeyElements, resp->iTransportScheme );
       
  1430         iDomainId.SetLength( 0 );
       
  1431         CleanupStack::PopAndDestroy( context );
       
  1432 
       
  1433         if ( iDomainRightsResp )
       
  1434             {
       
  1435             // It's a implicit Join Domain case
       
  1436             // We still need to store the domain RO
       
  1437             StoreDomainRightsL();
       
  1438             }
       
  1439 
       
  1440         // Device DRM Time is insecure, but server thinks that the time is correct
       
  1441         // -> Set DRM Time as secure
       
  1442         if ( !iSecureTime )
       
  1443             {
       
  1444             SetDrmTimeSecureL();
       
  1445             }
       
  1446         }
       
  1447     else
       
  1448         {
       
  1449         if ( resp->iErrorUrl )
       
  1450             {
       
  1451             if ( iObserver )
       
  1452                 {
       
  1453                 iObserver->ErrorUrlL( *resp->iErrorUrl );
       
  1454                 }
       
  1455             }
       
  1456         iSigner->ResetResponses();
       
  1457         }
       
  1458     CleanupStack::PopAndDestroy( &domainKeyElements );
       
  1459     }
       
  1460 
       
  1461 // ---------------------------------------------------------
       
  1462 // CRoapEng::HandleLeaveDomainResponseL()
       
  1463 // ---------------------------------------------------------
       
  1464 //
       
  1465 void CRoapEng::HandleLeaveDomainResponsePduL( const TDesC8& aLeaveResp )
       
  1466     {
       
  1467     LOGLIT( "CRoapEng::HandleLeaveDomainResponsePduL" )
       
  1468 
       
  1469     __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
  1470 
       
  1471     CLeaveDomainResp* resp = NULL;
       
  1472     resp = iParser->ParseLeaveDomainRespL( aLeaveResp );
       
  1473     iRoapStatus = resp->iStatus;
       
  1474     iResponse = resp;
       
  1475     if ( iRoapStatus == ESuccess )
       
  1476         {
       
  1477 
       
  1478         }
       
  1479     else if ( resp->iErrorUrl )
       
  1480         {
       
  1481         if ( iObserver )
       
  1482             {
       
  1483             iObserver->ErrorUrlL( *resp->iErrorUrl );
       
  1484             }
       
  1485         }
       
  1486 
       
  1487     PERFORMANCE_LOGLIT( "Leave domain protocol completed" )
       
  1488     }
       
  1489 
       
  1490 // ---------------------------------------------------------
       
  1491 // CRoapEng::HandleMeteringReportResponsePduL()
       
  1492 // ---------------------------------------------------------
       
  1493 //
       
  1494 #ifndef RD_DRM_METERING
       
  1495 void CRoapEng::HandleMeteringReportResponsePduL( const TDesC8& /*aMeteringResp*/)
       
  1496     {
       
  1497     }
       
  1498 #else
       
  1499 void CRoapEng::HandleMeteringReportResponsePduL( const TDesC8& aMeteringResp )
       
  1500     {
       
  1501     LOGLIT( "CRoapEng::HandleMeteringReportResponsePduL" )
       
  1502     __ASSERT_ALWAYS( iStoredRiContext, User::Invariant() );
       
  1503 
       
  1504     CMeteringResp* resp = NULL;
       
  1505     CMeteringReportReq* request = NULL;
       
  1506 
       
  1507     resp = iParser->ParseMeteringRespL( aMeteringResp );
       
  1508 
       
  1509     request = static_cast<CMeteringReportReq*> ( iRequest );
       
  1510 
       
  1511     iRoapStatus = resp->iStatus;
       
  1512     iResponse = resp;
       
  1513     if ( iRoapStatus == ESuccess )
       
  1514         {
       
  1515         if ( resp->iDeviceId.CompareF( *iDeviceId ) != KErrNone
       
  1516             || resp->iDeviceNonce->CompareF( request->iNonce ) != KErrNone )
       
  1517             {
       
  1518             LOGLIT( "Mismatch in deviceId or in nonce" )
       
  1519             LOGLIT( "Observed DeviceId" )
       
  1520             LOGHEX( resp->iDeviceId.Ptr(), resp->iDeviceId.Length() )
       
  1521             LOGLIT( "Expected DeviceId" )
       
  1522             LOGHEX( request->iDeviceId.Ptr(), request->iDeviceId.Length() )
       
  1523             LOGLIT( "Observed nonce" )
       
  1524             LOGHEX( resp->iDeviceNonce->Ptr(), resp->iDeviceNonce->Length() )
       
  1525             LOGLIT( "Expected nonce" )
       
  1526             User::Leave( KErrRoapServerFatal );
       
  1527             }
       
  1528 
       
  1529         if ( !iStoredRiContext || ( resp->iCertificateChain.Count()
       
  1530             && resp->iOcspResponse.Count() ) )
       
  1531             {
       
  1532             if ( !VerifyCertificateChainL( resp->iCertificateChain,
       
  1533                 resp->iOcspResponse ) )
       
  1534                 {
       
  1535                 LOGLIT( "Certificate chain validation failed" )
       
  1536                 User::Leave( KErrRoapServerFatal );
       
  1537                 }
       
  1538             if ( !ValidateRiIdL( resp->iRiId, *resp->iCertificateChain[0] ) )
       
  1539                 {
       
  1540                 LOGLIT( "RI ID validation failed" )
       
  1541                 User::Leave( KErrRoapServerFatal );
       
  1542                 }
       
  1543             }
       
  1544 
       
  1545         if ( !VerifySignatureL( aMeteringResp, *resp->iSignature,
       
  1546             iStoredRiContext->CertificateChain() ) )
       
  1547             {
       
  1548             LOGLIT( "Signature verification failed" )
       
  1549             User::Leave( KErrRoapServerFatal );
       
  1550             }
       
  1551 
       
  1552         // Everything is fine, we can delete metering data
       
  1553         iStorageClient->DeleteMeteringDataL( resp->iRiId );
       
  1554 
       
  1555         // notify PostResponseUrl for iObserver
       
  1556         if ( resp->iPrUrl )
       
  1557             {
       
  1558             HBufC8* prUrl( resp->iPrUrl );
       
  1559             LOGLIT( "PrUrl" )
       
  1560             LOGHEX( prUrl->Ptr(), prUrl->Length() )
       
  1561             if ( iObserver )
       
  1562                 {
       
  1563                 iObserver->PostResponseUrlL( *prUrl );
       
  1564                 LOGLIT( "Notified observer with PostResponseUrl" )
       
  1565                 }
       
  1566             else
       
  1567                 {
       
  1568                 LOGLIT( "Warning no observer for PostResponseUrl" )
       
  1569                 }
       
  1570             }
       
  1571         }
       
  1572     return;
       
  1573     }
       
  1574 #endif //RD_DRM_METERING
       
  1575 // ---------------------------------------------------------
       
  1576 // CRoapEng::HandleMultipartL()
       
  1577 // ---------------------------------------------------------
       
  1578 //
       
  1579 void CRoapEng::HandleMultipartL()
       
  1580     {
       
  1581     LOGLIT( "CRoapEng::HandleMultipartL" )
       
  1582 
       
  1583     TInt rightsErr( KErrNone );
       
  1584     TInt err( KErrNone );
       
  1585     TInt docErr( KErrNone );
       
  1586     TDataType type = TDataType();
       
  1587     TBool mmcAllowed( EFalse );
       
  1588     HBufC* contentName( NULL );
       
  1589     RBuf newPath;
       
  1590     TUid app_uid;
       
  1591     RBuf rootPath;
       
  1592 
       
  1593     TRAP( rightsErr, HandleRoapResponseL( iRoapResp->ProtocolUnit() ) );
       
  1594 
       
  1595     newPath.CreateL( KMaxFileName );
       
  1596     CleanupClosePushL( newPath  );
       
  1597 
       
  1598     CDocumentHandler* docHandler( CDocumentHandler::NewLC() );
       
  1599 
       
  1600     if ( iRoapResp->DcfFileName().Left( 1 ).CompareF( _L ("e") ) == 0 )
       
  1601         {
       
  1602         mmcAllowed = ETrue;
       
  1603         }
       
  1604 
       
  1605     RFs fs;
       
  1606     User::LeaveIfError( fs.Connect() );
       
  1607     CleanupClosePushL( fs );
       
  1608 
       
  1609 #ifndef RD_MULTIPLE_DRIVE
       
  1610     rootPath.CreateL( mmcAllowed ?
       
  1611         PathInfo::MemoryCardRootPath() :
       
  1612         PathInfo::PhoneMemoryRootPath() );
       
  1613 
       
  1614 #else //RD_MULTIPLE_DRIVE
       
  1615     _LIT( KSysDriveRoot, "_:\\Data\\");
       
  1616     _LIT( KMassDriveRoot, "_:\\" );
       
  1617     TInt driveNumber( -1 );
       
  1618     TChar driveLetter;
       
  1619 
       
  1620     if ( mmcAllowed )
       
  1621         {
       
  1622         // Set root path to memory card root
       
  1623         rootPath.CreateL( KMassDriveRoot() );
       
  1624         DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, driveNumber );
       
  1625         }
       
  1626     else
       
  1627         {
       
  1628         // Set root path to system root
       
  1629         rootPath.CreateL( KSysDriveRoot() );
       
  1630         DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
       
  1631         }
       
  1632     fs.DriveToChar( driveNumber, driveLetter );
       
  1633     __ASSERT_ALWAYS( rootPath.Length()>0, User::Invariant() );
       
  1634     rootPath[0] = (TUint)driveLetter;
       
  1635 
       
  1636 
       
  1637 #endif
       
  1638     CleanupClosePushL( rootPath );
       
  1639 
       
  1640     iRoapResp->GetContentNameLC( contentName );
       
  1641 
       
  1642     if ( contentName && contentName->Length()
       
  1643         && fs.IsValidName( *contentName ) )
       
  1644         {
       
  1645         if ( !rightsErr )
       
  1646             {
       
  1647             TRAP( err, docErr = docHandler->SilentMoveL( iRoapResp->DcfFileName(),
       
  1648                     *contentName, rootPath, type, KEntryAttNormal ) );
       
  1649             }
       
  1650         else
       
  1651             {
       
  1652             // when an error occured during RO storing -> show "saved to" note
       
  1653             TRAP( err, docErr = docHandler->MoveL( iRoapResp->DcfFileName(),
       
  1654                     *contentName, type, KEntryAttNormal ) );
       
  1655             }
       
  1656 
       
  1657         }
       
  1658     else
       
  1659         {
       
  1660         if ( !rightsErr )
       
  1661             {
       
  1662             // use the default name
       
  1663             User::LeaveIfError( docHandler->SilentMoveL(
       
  1664                 iRoapResp->DcfFileName(), KNullDesC(), rootPath, type,
       
  1665                 KEntryAttNormal ) );
       
  1666             }
       
  1667         else
       
  1668             {
       
  1669             // when an error occured during RO storing -> show "saved to" note
       
  1670             docHandler->MoveL( iRoapResp->DcfFileName(), KNullDesC(), type,
       
  1671                 KEntryAttNormal );
       
  1672             }
       
  1673         }
       
  1674 
       
  1675     if ( err || docErr )
       
  1676         {
       
  1677         if ( !rightsErr )
       
  1678             {
       
  1679             // use the default name
       
  1680             User::LeaveIfError( docHandler->SilentMoveL(
       
  1681                 iRoapResp->DcfFileName(), KNullDesC(), rootPath, type,
       
  1682                 KEntryAttNormal ) );
       
  1683             }
       
  1684         else
       
  1685             {
       
  1686             // when an error occured during RO storing -> show "saved to" note
       
  1687             docHandler->MoveL( iRoapResp->DcfFileName(), KNullDesC(), type,
       
  1688                 KEntryAttNormal );
       
  1689             }
       
  1690         }
       
  1691     User::LeaveIfError( rightsErr );
       
  1692 
       
  1693     User::LeaveIfError( docHandler->GetPath( newPath ) );
       
  1694     User::LeaveIfError( docHandler->HandlerAppUid( app_uid ) );
       
  1695 
       
  1696     if ( iObserver )
       
  1697         {
       
  1698         iObserver->ContentDetailsL( newPath, type.Des8(), app_uid );
       
  1699         }
       
  1700 
       
  1701     CleanupStack::PopAndDestroy( contentName );
       
  1702     CleanupStack::PopAndDestroy( &rootPath );
       
  1703 
       
  1704     CleanupStack::PopAndDestroy( &fs );
       
  1705     CleanupStack::PopAndDestroy( docHandler );
       
  1706     CleanupStack::PopAndDestroy( &newPath );
       
  1707     }
       
  1708 
       
  1709 // ---------------------------------------------------------
       
  1710 // CRoapEng::SignMessageL()
       
  1711 // ---------------------------------------------------------
       
  1712 //
       
  1713 HBufC8* CRoapEng::SignMessageL( const TDesC8& aMessage ) const
       
  1714     {
       
  1715     LOGLIT( "CRoapEng::SignMessageL" )
       
  1716     HBufC8* r = NULL;
       
  1717 
       
  1718     if ( iReqMessage == EDeviceHello )
       
  1719         {
       
  1720         // Device Hello always resets signing chain!!
       
  1721         iSigner->ResetRequests();
       
  1722         iSigner->ResetResponses();
       
  1723         // Device Hello or RI Hello is not signed
       
  1724         iSigner->AddRequestL( aMessage );
       
  1725         r = aMessage.AllocL();
       
  1726         }
       
  1727     else
       
  1728         {
       
  1729         r = iSigner->SignAndAddRequestL( aMessage );
       
  1730         iSigner->ResetRequests();
       
  1731 
       
  1732         if ( iReqMessage == ERegistration )
       
  1733             {
       
  1734             // Add signed request to the signer for verifying signature on
       
  1735             // response (for Registration protocol only).
       
  1736             iSigner->AddResponseL( *r );
       
  1737             }
       
  1738         }
       
  1739     return r;
       
  1740     }
       
  1741 
       
  1742 // ---------------------------------------------------------
       
  1743 // CRoapEng::VerifySignatureL()
       
  1744 // ---------------------------------------------------------
       
  1745 //
       
  1746 TBool CRoapEng::VerifySignatureL(
       
  1747     const TDesC8& aMessage,
       
  1748     const TDesC8& aSignature,
       
  1749     const RPointerArray<HBufC8>& aCertificateChain ) const
       
  1750     {
       
  1751     LOGLIT( "CRoapEng::VerifySignatureL" )
       
  1752 
       
  1753     TBool isValid = ETrue;
       
  1754 
       
  1755     if ( iReqMessage != EDeviceHello && iReqMessage != ELeaveDomain )
       
  1756         {
       
  1757         // RI Hello and Leave Domain resp are not signed
       
  1758         isValid = iSigner->VerifyAndAddResponseL( aMessage, aSignature,
       
  1759             aCertificateChain );
       
  1760         iSigner->ResetResponses();
       
  1761         }
       
  1762 
       
  1763 #ifdef _DISABLE_SIGNATURE_CHECK
       
  1764     isValid = ETrue;
       
  1765 #endif
       
  1766     return isValid;
       
  1767     }
       
  1768 
       
  1769 // ---------------------------------------------------------
       
  1770 // CRoapEng::VerifyTriggerSignatureL()
       
  1771 // ---------------------------------------------------------
       
  1772 //
       
  1773 TBool CRoapEng::VerifyTriggerSignatureL(
       
  1774     const TDesC8& aXmlTrigger,
       
  1775     const CRoapTrigger& aTrigger ) const
       
  1776     {
       
  1777     LOGLIT( "CRoapEng::ValidateTriggerSignatureL" )
       
  1778 
       
  1779     TPtrC8 element( KNullDesC8 );
       
  1780     TPtrC8 signedInfo( KNullDesC8 );
       
  1781     CDRMDomainContext* context( NULL );
       
  1782     HBufC8* domainKey( NULL );
       
  1783     HBufC8* unwrappedMacKey( NULL );
       
  1784     CSHA1* digest( NULL );
       
  1785     CMessageDigest* hMac( NULL );
       
  1786     TBool result( ETrue );
       
  1787     TInt pos( 0 );
       
  1788     TInt generation( 0 );
       
  1789 
       
  1790     element.Set( iParser->ExtractElement( aXmlTrigger, KLeaveDomainElement(),
       
  1791         pos ) );
       
  1792     pos = 0;
       
  1793     signedInfo.Set( iParser->ExtractElement( aXmlTrigger,
       
  1794         KSignedInfoElement(), pos ) );
       
  1795 
       
  1796     if ( !element.Length() || !signedInfo.Length() || !aTrigger.iEncKey
       
  1797         || !aTrigger.iSignature )
       
  1798         {
       
  1799         User::Leave( KErrRoapServerFatal );
       
  1800         }
       
  1801 
       
  1802     context = iStorageClient->GetDomainContextL( *aTrigger.iDomainId );
       
  1803 
       
  1804     if ( !context )
       
  1805         {
       
  1806         // we are not member of the domain
       
  1807         LOGLIT( "No DomainContext for the domain -> Cannot verify Trigger signature" )
       
  1808         return ETrue;
       
  1809         }
       
  1810     CleanupStack::PushL( context );
       
  1811 
       
  1812     TLex8 lex( aTrigger.iDomainId->Right( KDomainGenerationLength ) );
       
  1813     lex.Val( generation );
       
  1814     domainKey = context->DomainKeyL( generation );
       
  1815     User::LeaveIfNull( domainKey );
       
  1816     CleanupStack::PushL( domainKey );
       
  1817 
       
  1818     unwrappedMacKey = OmaCrypto::AesUnwrapL( *domainKey, *aTrigger.iEncKey );
       
  1819     CleanupStack::PopAndDestroy( domainKey );
       
  1820     CleanupStack::PushL( unwrappedMacKey );
       
  1821 
       
  1822     // hash the leaveDomain element
       
  1823     digest = CSHA1::NewL();
       
  1824     CleanupStack::PushL( digest );
       
  1825     digest->Update( element );
       
  1826 
       
  1827     if ( digest->Final().CompareF( *aTrigger.iDigestValue ) )
       
  1828         {
       
  1829         LOGLIT( "Reference Validation failed!" )
       
  1830         result = EFalse;
       
  1831         }
       
  1832 
       
  1833     if ( result )
       
  1834         {
       
  1835         // calculate HMAC signature
       
  1836         hMac = CMessageDigestFactory::NewHMACLC( CMessageDigest::ESHA1,
       
  1837             *unwrappedMacKey );
       
  1838         hMac->Update( signedInfo );
       
  1839 
       
  1840         if ( hMac->Final().CompareF( *aTrigger.iSignature ) != 0 )
       
  1841             {
       
  1842             LOGLIT( "Signature Validation failed!" )
       
  1843             result = EFalse;
       
  1844             }
       
  1845         CleanupStack::PopAndDestroy( hMac );
       
  1846         }
       
  1847 
       
  1848     CleanupStack::PopAndDestroy( digest );
       
  1849     CleanupStack::PopAndDestroy( unwrappedMacKey );
       
  1850     CleanupStack::PopAndDestroy( context );
       
  1851 
       
  1852     if ( !result )
       
  1853         {
       
  1854         LOGLIT( "Trigger signature check failed!" )
       
  1855         }
       
  1856 
       
  1857 #ifdef _DISABLE_SIGNATURE_CHECK
       
  1858     result = ETrue;
       
  1859 #endif
       
  1860     return result;
       
  1861     }
       
  1862 
       
  1863 // ---------------------------------------------------------
       
  1864 // CRoapEng::VerifyCertificateChainL()
       
  1865 // ---------------------------------------------------------
       
  1866 //
       
  1867 TBool CRoapEng::VerifyCertificateChainL(
       
  1868     const RPointerArray<HBufC8>& aCertificateChain,
       
  1869     const RPointerArray<HBufC8>& aOcspResponses ) const
       
  1870     {
       
  1871     LOGLIT( "CRoapEng::VerifyCertificateChainL" )
       
  1872 
       
  1873     CX509Certificate* cert = NULL;
       
  1874     CX509Certificate* signingCert = NULL;
       
  1875     CX509Certificate* riCA = NULL;
       
  1876     TBool result = EFalse;
       
  1877     RPointerArray<HBufC8> serialNums;
       
  1878     CX500DistinguishedName* rootDistName = NULL;
       
  1879     HBufC* rootName = NULL;
       
  1880     HBufC8* rootCert = NULL;
       
  1881     HBufC8* temp = NULL;
       
  1882 
       
  1883     if ( !aCertificateChain.Count() || !aOcspResponses.Count() )
       
  1884         {
       
  1885         User::Leave( KErrRoapServerFatal );
       
  1886         }
       
  1887 
       
  1888     // Get the last cert from the chain. It is signed by some of our trusted anchor
       
  1889     riCA = CX509Certificate::NewLC(
       
  1890         *( aCertificateChain[aCertificateChain.Count() - 1] ) );
       
  1891     rootDistName = CX500DistinguishedName::NewLC( riCA->IssuerName() );
       
  1892     rootName = rootDistName->DisplayNameL();
       
  1893     CleanupStack::PushL( rootName );
       
  1894     // Get the correct root cert for validating the whole chain
       
  1895     rootCert = iStorageClient->GetRootCertificateL( *rootName );
       
  1896     CleanupStack::PopAndDestroy( rootName );
       
  1897     CleanupStack::PopAndDestroy( rootDistName );
       
  1898     CleanupStack::PopAndDestroy( riCA );
       
  1899 
       
  1900     if ( !rootCert )
       
  1901         {
       
  1902         LOGLIT( "No root certificate present!" )
       
  1903         LOGLIT( "Certificate chain verification failed." )
       
  1904         return EFalse;
       
  1905         }
       
  1906     CleanupStack::PushL( rootCert );
       
  1907 
       
  1908     CleanupResetAndDestroyPushL( serialNums );
       
  1909 
       
  1910     for ( TInt i = 0; i < aCertificateChain.Count(); i++ )
       
  1911         {
       
  1912         cert = CX509Certificate::NewLC( *aCertificateChain[i] );
       
  1913         temp = cert->SerialNumber().AllocLC();
       
  1914         serialNums.AppendL( temp );
       
  1915         CleanupStack::Pop( temp );
       
  1916         if ( aCertificateChain.Count() - 1 == i )
       
  1917             {
       
  1918             // signingCert = Trusted root cert
       
  1919             signingCert = CX509Certificate::NewLC( *rootCert );
       
  1920             }
       
  1921         else
       
  1922             {
       
  1923             signingCert = CX509Certificate::NewLC( *aCertificateChain[i + 1] );
       
  1924             }
       
  1925         result = cert->VerifySignatureL( signingCert->PublicKey().KeyData() );
       
  1926 
       
  1927 #ifdef _DISABLE_CERT_CHECK
       
  1928         result = ETrue;
       
  1929 #endif
       
  1930         CleanupStack::PopAndDestroy( signingCert );
       
  1931         CleanupStack::PopAndDestroy( cert );
       
  1932         if ( !result )
       
  1933             {
       
  1934             LOGLIT( "Certificate chain verification failed." )
       
  1935             CleanupStack::PopAndDestroy( 2, rootCert );
       
  1936             return result;
       
  1937             }
       
  1938         }
       
  1939 
       
  1940     if ( aCertificateChain.Count() >= 2 )
       
  1941         {
       
  1942         result = VerifyOcspResponsesL( aOcspResponses, *aCertificateChain[1],
       
  1943             serialNums );
       
  1944 
       
  1945         if ( !result )
       
  1946             {
       
  1947             // CoreMedia's OCSP responder cert is signed by the root -> against CMLA spec
       
  1948             LOGLIT( "Try to verify OCSP response cert using root cert" )
       
  1949             result = VerifyOcspResponsesL( aOcspResponses, *rootCert,
       
  1950                 serialNums );
       
  1951             }
       
  1952         }
       
  1953     else if ( aCertificateChain.Count() == 1 )
       
  1954         {
       
  1955         // There is only one cert in the cert chain -> the OCSP response cert is verified with root cert
       
  1956         result = VerifyOcspResponsesL( aOcspResponses, *rootCert, serialNums );
       
  1957         }
       
  1958     else
       
  1959         {
       
  1960         result = EFalse;
       
  1961         }
       
  1962 
       
  1963     if ( iStoredRiContext && aCertificateChain.Count() && result )
       
  1964         {
       
  1965         cert = CX509Certificate::NewLC( *aCertificateChain[0] );
       
  1966         if ( iStoredRiContext->ExpiryTime() < cert->ValidityPeriod().Finish() )
       
  1967             {
       
  1968             iStoredRiContext->SetCertificateChainL( aCertificateChain );
       
  1969             iStoredRiContext->SetOCSPResponseL( aOcspResponses );
       
  1970 
       
  1971             // update RI Context
       
  1972             iStorageClient->AddRIContextL( *iStoredRiContext );
       
  1973             }
       
  1974         CleanupStack::PopAndDestroy( cert );
       
  1975         }
       
  1976 
       
  1977     CleanupStack::PopAndDestroy( 2, rootCert ); // serialNums, rootCert
       
  1978 
       
  1979 #ifdef _ROAP_TESTING
       
  1980     if ( result )
       
  1981         {
       
  1982         LOGLIT( "Certificate chain verification ok." )
       
  1983         }
       
  1984     else
       
  1985         {
       
  1986         LOGLIT( "Certificate chain verification failed." )
       
  1987         }
       
  1988 #endif
       
  1989 #ifdef _DISABLE_CERT_CHECK
       
  1990     result = ETrue;
       
  1991 #endif
       
  1992 
       
  1993     return result;
       
  1994     }
       
  1995 
       
  1996 // ---------------------------------------------------------
       
  1997 // CRoapEng::VerifyOcspResponsesL()
       
  1998 // ---------------------------------------------------------
       
  1999 //
       
  2000 TBool CRoapEng::VerifyOcspResponsesL(
       
  2001     const RPointerArray<HBufC8>& aOcspResponses,
       
  2002     const TDesC8& aRiCaCert,
       
  2003     const RPointerArray<HBufC8>& aCertSerialNums ) const
       
  2004     {
       
  2005     LOGLIT( "CRoapEng::VerifyOcspResponsesL" )
       
  2006 
       
  2007 #ifdef _DISABLE_OCSP_CHECK
       
  2008     TBool result( ETrue );
       
  2009 #else
       
  2010     // Get verification result from the server
       
  2011     TBool result( iStorageClient->VerifyOcspResponsesL( aOcspResponses,
       
  2012         aRiCaCert, aCertSerialNums ) );
       
  2013 #endif
       
  2014 
       
  2015 #ifdef _ROAP_TESTING
       
  2016     if ( result )
       
  2017         {
       
  2018         LOGLIT( "OCSP response verification ok." )
       
  2019         }
       
  2020     else
       
  2021         {
       
  2022         LOGLIT( "OCSP response verification failed." )
       
  2023         }
       
  2024 #endif
       
  2025 
       
  2026     return result;
       
  2027     }
       
  2028 
       
  2029 // ---------------------------------------------------------
       
  2030 // CRoapEng::ValidateRiCertificateL()
       
  2031 // ---------------------------------------------------------
       
  2032 //
       
  2033 TBool CRoapEng::ValidateRiCertificateL( const CX509Certificate* aCert )
       
  2034     {
       
  2035     LOGLIT( "CRoapEng::ValidateRiCertificateL" )
       
  2036 
       
  2037     TBool ret = ETrue;
       
  2038     const CX509CertExtension* ext = NULL;
       
  2039     CX509KeyUsageExt* keyUsageExt = NULL;
       
  2040     CX509ExtendedKeyUsageExt* extendedKeyUsage = NULL;
       
  2041     TTime riExpiry;
       
  2042     TInt count = 0;
       
  2043 
       
  2044     if ( iSelectedAlgorithms == ECmlaIp1 )
       
  2045         {
       
  2046         // Check RI certificate extensions only in CMLA case
       
  2047         ext = aCert->Extension( KKeyUsage() );
       
  2048         if ( !ext || !( ext->Critical() ) )
       
  2049             {
       
  2050             LOGLIT( "RI cert KeyUsage extension missing or not critical!" )
       
  2051             ret = EFalse;
       
  2052             }
       
  2053 
       
  2054         if ( ext && ret )
       
  2055             {
       
  2056             keyUsageExt = CX509KeyUsageExt::NewLC( ext->Data() );
       
  2057             if ( !keyUsageExt->IsSet( EX509DigitalSignature ) )
       
  2058                 {
       
  2059                 LOGLIT( "DigitalSignature bit is not set in KeyUsageExt of RI cert!" )
       
  2060                 ret = EFalse;
       
  2061                 }
       
  2062             CleanupStack::PopAndDestroy( keyUsageExt );
       
  2063             }
       
  2064 
       
  2065         ext = aCert->Extension( KExtendedKeyUsage() );
       
  2066         if ( !ext || !( ext->Critical() ) )
       
  2067             {
       
  2068             LOGLIT( "RI cert ExtendedKeyUsage extension missing or not critical!" )
       
  2069             ret = EFalse;
       
  2070             }
       
  2071 
       
  2072         if ( ext && ret )
       
  2073             {
       
  2074             ret = EFalse;
       
  2075             extendedKeyUsage = CX509ExtendedKeyUsageExt::NewLC( ext->Data() );
       
  2076             count = extendedKeyUsage->KeyUsages().Count();
       
  2077             for ( TInt i = 0; i < count && !ret; i++ )
       
  2078                 {
       
  2079                 if ( extendedKeyUsage->KeyUsages().At( i )->CompareF(
       
  2080                     KOmaKpRightsIssuerOid() ) == 0 )
       
  2081                     {
       
  2082                     ret = ETrue;
       
  2083                     }
       
  2084                 }
       
  2085             if ( !ret )
       
  2086                 {
       
  2087                 LOGLIT( "OmaKpRightsIssuer OID is not set in ExtendedKeyUsageExt of RI cert!" )
       
  2088                 }
       
  2089             CleanupStack::PopAndDestroy( extendedKeyUsage );
       
  2090             }
       
  2091         }
       
  2092 
       
  2093     riExpiry = aCert->ValidityPeriod().Finish();
       
  2094 
       
  2095     if ( riExpiry < GetDrmTimeL() )
       
  2096         {
       
  2097         LOGLIT( "RI Context certificate is expired!" )
       
  2098         ret = EFalse;
       
  2099         }
       
  2100 #ifdef _DISABLE_CERT_CHECK
       
  2101     ret = ETrue;
       
  2102 #endif
       
  2103     return ret;
       
  2104     }
       
  2105 
       
  2106 // ---------------------------------------------------------
       
  2107 // CRoapEng::GetCertificateChainL()
       
  2108 // ---------------------------------------------------------
       
  2109 //
       
  2110 RPointerArray<HBufC8> CRoapEng::GetCertificateChainL() const
       
  2111     {
       
  2112     LOGLIT( "CRoapEng::GetCertificateChainL ->" )
       
  2113 
       
  2114     TInt err = KErrNone;
       
  2115     RPointerArray<HBufC8> certificateChain;
       
  2116     HBufC8* root = NULL;
       
  2117 
       
  2118     CleanupResetAndDestroyPushL( certificateChain );
       
  2119 
       
  2120     err = iStorageClient->GetDeviceCertificateChainL( certificateChain );
       
  2121 
       
  2122     if ( err )
       
  2123         {
       
  2124         User::Leave( err );
       
  2125         }
       
  2126 
       
  2127     if ( certificateChain.Count() < KMinCertChainLength )
       
  2128         {
       
  2129         // the CMLA chain must always contain:
       
  2130         // the device certificate,
       
  2131         // at lest one signing certificate (device CA),
       
  2132         // and the root certificate
       
  2133         DETAILLOGLIT( "Got improper certificate chain!!" )
       
  2134         // Leaving in production devices.
       
  2135         User::Leave( KErrRoapDevice );
       
  2136         __ASSERT_DEBUG( ETrue, User::Invariant() );
       
  2137         }
       
  2138 
       
  2139     // delete and remove the root certificate (it's always the last one in the list)
       
  2140     root = certificateChain[certificateChain.Count() - 1];
       
  2141     delete root;
       
  2142     certificateChain.Remove( certificateChain.Count() - 1 );
       
  2143 
       
  2144     CleanupStack::Pop( &certificateChain );
       
  2145 
       
  2146     LOGLIT( "CRoapEng::GetCertificateChainL <-" )
       
  2147 
       
  2148     return certificateChain;
       
  2149     }
       
  2150 
       
  2151 // ---------------------------------------------------------
       
  2152 // CRoapEng::GetDeviceDetailsL()
       
  2153 // ---------------------------------------------------------
       
  2154 //
       
  2155 void CRoapEng::GetDeviceDetailsL(
       
  2156     HBufC8*& aManufacturer,
       
  2157     HBufC8*& aModel,
       
  2158     HBufC8*& aVersion )
       
  2159     {
       
  2160     LOGLIT( "-> CRoapEng::GetDeviceDetailsL" )
       
  2161 
       
  2162 #ifndef __WINS__
       
  2163     TInt numPhone = 0;
       
  2164     TUint32 caps = 0;
       
  2165     TName tsyName;
       
  2166     RMobilePhone phone;
       
  2167     RTelServer etelServer;
       
  2168     RTelServer::TPhoneInfo phoneInfo;
       
  2169     HBufC* version = NULL;
       
  2170 
       
  2171     User::LeaveIfError( etelServer.Connect() );
       
  2172 
       
  2173     CleanupClosePushL( etelServer );
       
  2174 
       
  2175     User::LeaveIfError( etelServer.LoadPhoneModule( KMmTsyModuleName ) );
       
  2176     User::LeaveIfError( etelServer.EnumeratePhones( numPhone) );
       
  2177 
       
  2178     for (TInt i(0); i < numPhone; i++)
       
  2179         {
       
  2180         User::LeaveIfError( etelServer.GetPhoneInfo( i, phoneInfo ) );
       
  2181         User::LeaveIfError( etelServer.GetTsyName( i,tsyName ) );
       
  2182 
       
  2183         if ( tsyName.CompareF( KMmTsyModuleName ) == 0)
       
  2184             {
       
  2185             break;
       
  2186             }
       
  2187         }
       
  2188 
       
  2189     User::LeaveIfError( phone.Open( etelServer, phoneInfo.iName ) );
       
  2190     CleanupClosePushL( phone );
       
  2191 
       
  2192     phone.GetIdentityCaps( caps );
       
  2193     if ( !( caps & RMobilePhone::KCapsGetManufacturer ) &&
       
  2194         !( caps & RMobilePhone::KCapsGetModel ) )
       
  2195         {
       
  2196         User::Leave( KErrRoapGeneral );
       
  2197         }
       
  2198 
       
  2199     RMobilePhone::TMobilePhoneIdentityV1 details;
       
  2200     TRequestStatus status;
       
  2201 
       
  2202     phone.GetPhoneId( status, details );
       
  2203     User::WaitForRequest( status );
       
  2204 
       
  2205     User::LeaveIfError( status.Int() );
       
  2206 
       
  2207     HBufC8* manufacturer( HBufC8::NewLC( details.iManufacturer.Length() ) );
       
  2208     manufacturer->Des().Copy( details.iManufacturer );
       
  2209     HBufC8* model( HBufC8::NewLC( details.iModel.Length() ) );
       
  2210     model->Des().Copy( details.iModel );
       
  2211 
       
  2212     version = HBufC::NewLC( KSysUtilVersionTextLength );
       
  2213     TPtr ptr( version->Des() );
       
  2214     User::LeaveIfError( SysUtil::GetSWVersion( ptr ) );
       
  2215 
       
  2216     // remove possible BOM from the end
       
  2217     if ( ptr.Right( KBOM1().Length() ).CompareF( KBOM1 ) == KErrNone )
       
  2218         {
       
  2219         ptr.Delete( ptr.Length() - KBOM1().Length(), KBOM1().Length() );
       
  2220         }
       
  2221     if ( ptr.Right( KBOM2().Length() ).CompareF( KBOM2 ) == KErrNone )
       
  2222         {
       
  2223         ptr.Delete( ptr.Length() - KBOM2().Length(), KBOM2().Length() );
       
  2224         }
       
  2225 
       
  2226     aVersion = CnvUtfConverter::ConvertFromUnicodeToUtf8L( ptr );
       
  2227 
       
  2228     CleanupStack::PopAndDestroy( version );
       
  2229     CleanupStack::Pop( model );
       
  2230     CleanupStack::Pop( manufacturer );
       
  2231     aManufacturer = manufacturer;
       
  2232     aModel = model;
       
  2233     CleanupStack::PopAndDestroy( &phone );
       
  2234     CleanupStack::PopAndDestroy( &etelServer );
       
  2235 #else
       
  2236     aManufacturer = _L8("Nokia").AllocL();
       
  2237     aModel = _L8("Emulator").AllocL();
       
  2238     aVersion = _L8("9.0").AllocL();
       
  2239 #endif
       
  2240 
       
  2241     LOGLIT( "Device details:" )
       
  2242     LOGLIT( "   Manufacturer: " )
       
  2243     LOG( aManufacturer->Des() )
       
  2244     LOGLIT( "   Model: " )
       
  2245     LOG( aModel->Des() )
       
  2246     LOGLIT( "   Revision: " )
       
  2247     LOG( aVersion->Des() )
       
  2248 
       
  2249     LOGLIT( "<- CRoapEng::GetDeviceDetailsL" )
       
  2250     }
       
  2251 
       
  2252 // ---------------------------------------------------------
       
  2253 // CRoapEng::FetchTransactionIDL()
       
  2254 // ---------------------------------------------------------
       
  2255 //
       
  2256 void CRoapEng::FetchTransactionIDL(
       
  2257     RPointerArray<HBufC8>& aTransIDs,
       
  2258     RPointerArray<HBufC8>& aContentIDs )
       
  2259     {
       
  2260     LOGLIT( "CRoapEng::FetchTransactionIDL" )
       
  2261 
       
  2262     __ASSERT_ALWAYS( iTrigger, User::Invariant() );
       
  2263 
       
  2264     RArray<TPair> array;
       
  2265     TInt err = KErrNone;
       
  2266 
       
  2267     CleanupClosePushL( array );
       
  2268 
       
  2269     if ( !iTrigger->iContentIdList.Count() )
       
  2270         {
       
  2271         CleanupStack::PopAndDestroy( &array );
       
  2272         return;
       
  2273         }
       
  2274 
       
  2275     if ( iTransStatus == ENotAsked && iObserver )
       
  2276         {
       
  2277         UpdateTransactionTrackingStatusL();
       
  2278         }
       
  2279     if ( iTransStatus == EAllowed )
       
  2280         {
       
  2281         for ( TInt i = 0; i < iTrigger->iContentIdList.Count(); i++ )
       
  2282             {
       
  2283             TPair pair;
       
  2284             pair.iCid = iTrigger->iContentIdList[i]->Alloc(); // duplicate contentID,
       
  2285             pair.iTtid = NULL; // pair.iCid is deleted by iRequest
       
  2286             err = array.Append( pair );
       
  2287             if ( err )
       
  2288                 {
       
  2289                 delete pair.iCid;
       
  2290                 pair.iCid = NULL;
       
  2291                 }
       
  2292             }
       
  2293 
       
  2294             TRAP_IGNORE(iDcfRep->GetTtidL( array ) );
       
  2295 
       
  2296         for ( TInt i = 0; i < array.Count(); i++ )
       
  2297             {
       
  2298             if ( array[i].iTtid && array[i].iCid && array[i].iTtid->Length()
       
  2299                 && array[i].iCid->Length() )
       
  2300                 {
       
  2301                 err = aContentIDs.Append( array[i].iCid );
       
  2302                 if ( !err )
       
  2303                     {
       
  2304                     aTransIDs.Append( array[i].iTtid );
       
  2305                     }
       
  2306                 else
       
  2307                     {
       
  2308                     delete array[i].iCid;
       
  2309                     array[i].iCid = NULL;
       
  2310                     delete array[i].iTtid;
       
  2311                     array[i].iTtid = NULL;
       
  2312                     }
       
  2313                 }
       
  2314             else if ( array[i].iTtid || array[i].iCid )
       
  2315                 {
       
  2316                 delete array[i].iTtid;
       
  2317                 array[i].iTtid = NULL;
       
  2318                 delete array[i].iCid;
       
  2319                 array[i].iCid = NULL;
       
  2320                 }
       
  2321             }
       
  2322         }
       
  2323     CleanupStack::PopAndDestroy( &array );
       
  2324     }
       
  2325 
       
  2326 // ---------------------------------------------------------
       
  2327 // CRoapEng::InsertTransactionIDL()
       
  2328 // ---------------------------------------------------------
       
  2329 //
       
  2330 void CRoapEng::InsertTransactionIDL(
       
  2331     RPointerArray<HBufC8>& aTransIDs,
       
  2332     RPointerArray<HBufC8>& aContentIDs )
       
  2333     {
       
  2334     LOGLIT( "CRoapEng::InsertTransactionIDL" )
       
  2335 
       
  2336     RArray<TPair> array;
       
  2337     TRequestStatus status;
       
  2338 
       
  2339     CleanupClosePushL( array );
       
  2340 
       
  2341     if ( !aTransIDs.Count() || !aContentIDs.Count() )
       
  2342         {
       
  2343         LOGLIT( "Insert ttID: Wrong input data" )
       
  2344         CleanupStack::PopAndDestroy( &array );
       
  2345         return;
       
  2346         }
       
  2347 
       
  2348     if ( aTransIDs.Count() != aContentIDs.Count() )
       
  2349         {
       
  2350         LOGLIT( "Insert ttID: ttID.Count != cid.Count" )
       
  2351         CleanupStack::PopAndDestroy( &array );
       
  2352         return;
       
  2353         }
       
  2354 
       
  2355     if ( iTransStatus == ENotAsked && iObserver )
       
  2356         {
       
  2357         UpdateTransactionTrackingStatusL();
       
  2358         }
       
  2359     if ( iTransStatus == EAllowed )
       
  2360         {
       
  2361         for ( TInt i = 0; i < aContentIDs.Count() && i < aTransIDs.Count(); i++ )
       
  2362             {
       
  2363             TPair pair;
       
  2364             pair.iCid = aContentIDs[i];
       
  2365             pair.iTtid = aTransIDs[i];
       
  2366             array.Append( pair );
       
  2367             }
       
  2368 
       
  2369         iDcfRep->SetTtid( array, status );
       
  2370         User::WaitForRequest( status );
       
  2371         }
       
  2372 
       
  2373     CleanupStack::PopAndDestroy( &array );
       
  2374     }
       
  2375 
       
  2376 // ---------------------------------------------------------
       
  2377 // CRoapEng::GetOCSPResponderKeyHashL()
       
  2378 // ---------------------------------------------------------
       
  2379 //
       
  2380 HBufC8* CRoapEng::GetOCSPResponderKeyHashL() const
       
  2381     {
       
  2382     LOGLIT( "CRoapEng::GetOCSPResponderKeyHashL" )
       
  2383 
       
  2384     if ( !iStoredRiContext )
       
  2385         {
       
  2386         User::Leave( KErrRoapNotRegistered );
       
  2387         }
       
  2388     return iStorageClient->GetOcspResponderIdL( iStoredRiContext->RIID() );
       
  2389     }
       
  2390 
       
  2391 // ---------------------------------------------------------
       
  2392 // CRoapEng::GetDrmTimeL()
       
  2393 // ---------------------------------------------------------
       
  2394 //
       
  2395 TTime CRoapEng::GetDrmTimeL()
       
  2396     {
       
  2397     LOGLIT( "CRoapEng::GetDrmTimeL" )
       
  2398 
       
  2399     TTime drmTime;
       
  2400     DRMClock::ESecurityLevel secureTime;
       
  2401     TInt zone( 0 );
       
  2402 
       
  2403     User::LeaveIfError( iClockClient->GetSecureTime( drmTime, zone,
       
  2404         secureTime ) );
       
  2405 
       
  2406     if ( secureTime == DRMClock::KInsecure )
       
  2407         {
       
  2408         iSecureTime = EFalse;
       
  2409         }
       
  2410     else
       
  2411         {
       
  2412         iSecureTime = ETrue;
       
  2413         }
       
  2414 
       
  2415     return drmTime;
       
  2416     }
       
  2417 
       
  2418 // ---------------------------------------------------------
       
  2419 // CRoapEng::SetDrmTimeSecureL()
       
  2420 // ---------------------------------------------------------
       
  2421 //
       
  2422 void CRoapEng::SetDrmTimeSecureL()
       
  2423     {
       
  2424     LOGLIT( "CRoapEng::SetDrmTimeSecureL" )
       
  2425 
       
  2426     TTime drmTime;
       
  2427     DRMClock::ESecurityLevel secureTime;
       
  2428     TInt zone( 0 );
       
  2429 
       
  2430     User::LeaveIfError( iClockClient->GetSecureTime( drmTime, zone,
       
  2431         secureTime ) );
       
  2432     User::LeaveIfError( iClockClient->UpdateSecureTime( drmTime, zone ) );
       
  2433 
       
  2434     iSecureTime = ETrue;
       
  2435     }
       
  2436 
       
  2437 // ---------------------------------------------------------
       
  2438 // CRoapEng::AdjustDrmTime()
       
  2439 // ---------------------------------------------------------
       
  2440 //
       
  2441 void CRoapEng::AdjustDrmTimeL(
       
  2442     const RPointerArray<HBufC8>& aOcspResponses,
       
  2443     TDesC8& aRegReqNonce ) const
       
  2444     {
       
  2445     // To be removed on next API change.
       
  2446     // Replace calls with direct call to RRoapStorageClient.
       
  2447     LOGLIT( "CRoapEng::AdjustDrmTime calling server" )
       
  2448     if ( aOcspResponses.Count() > 0 )
       
  2449         {
       
  2450         iStorageClient->UpdateDrmTimeL( iStoredRiContext->CertificateChain(),
       
  2451             aOcspResponses, aRegReqNonce );
       
  2452         }
       
  2453     else
       
  2454         {
       
  2455         LOGLIT( "No OCSP responses present." )
       
  2456         }
       
  2457     }
       
  2458 
       
  2459 // ---------------------------------------------------------
       
  2460 // CRoapEng::StoreDomainRightsL()
       
  2461 // ---------------------------------------------------------
       
  2462 //
       
  2463 void CRoapEng::StoreDomainRightsL()
       
  2464     {
       
  2465     LOGLIT( "CRoapEng::StoreDomainRightsL" )
       
  2466 
       
  2467     RPointerArray<CDRMRights> returnedROs;
       
  2468 
       
  2469     CleanupResetAndDestroyPushL( returnedROs );
       
  2470 
       
  2471     iRoParser->ParseAndStoreL( *iDomainRightsResp, returnedROs );
       
  2472 
       
  2473     if ( iObserver )
       
  2474         {
       
  2475         iObserver->RightsObjectDetailsL( returnedROs ); // pass RO details to UI
       
  2476         }
       
  2477 
       
  2478     delete iDomainRightsResp;
       
  2479     iDomainRightsResp = NULL;
       
  2480 
       
  2481     iImplicitJoinDomain = EFalse;
       
  2482 
       
  2483     CleanupStack::PopAndDestroy( &returnedROs );
       
  2484     }
       
  2485 
       
  2486 // ---------------------------------------------------------
       
  2487 // CRoapEng::InsertDomainRosL()
       
  2488 // ---------------------------------------------------------
       
  2489 //
       
  2490 void CRoapEng::InsertDomainRosL()
       
  2491     {
       
  2492     CDcfRep* rep = NULL;
       
  2493     CDcfEntry* entry = NULL;
       
  2494     CContent* content = NULL;
       
  2495     TPtr8 ptr( NULL, 0 );
       
  2496     TInt i;
       
  2497     RFile file;
       
  2498     RFs fs;
       
  2499     TInt error( 0 );
       
  2500 
       
  2501     User::LeaveIfError( fs.Connect() );
       
  2502     CleanupClosePushL( fs );
       
  2503     rep = CDcfRep::NewL();
       
  2504     CleanupStack::PushL( rep );
       
  2505     for ( i = 0; i < iReturnedROs.Count(); i++ )
       
  2506         {
       
  2507         if ( iReturnedROs[i]->GetPermission().iDomainID )
       
  2508             {
       
  2509             rep->OrderListL( *iReturnedROs[i]->GetAsset().iUid );
       
  2510             entry = rep->NextL();
       
  2511             while ( entry )
       
  2512                 {
       
  2513                 CleanupStack::PushL( entry );
       
  2514                 error = file.Open( fs, entry->FileName(), EFileWrite
       
  2515                     | EFileShareReadersOrWriters );
       
  2516                 if ( !error )
       
  2517                     {
       
  2518                     CleanupClosePushL( file );
       
  2519                     content = CContent::NewLC( file );
       
  2520                     content->AgentSpecificCommand( EEmbedDomainRo,
       
  2521                         KNullDesC8, ptr );
       
  2522                     CleanupStack::PopAndDestroy( 2, &file ); // content, file
       
  2523                     }
       
  2524                 CleanupStack::PopAndDestroy( entry );
       
  2525                 entry = rep->NextL();
       
  2526                 }
       
  2527             }
       
  2528         }
       
  2529     CleanupStack::PopAndDestroy( 2, &fs ); // rep, fs
       
  2530     }
       
  2531 
       
  2532 // ---------------------------------------------------------
       
  2533 // CRoapEng::MapStatusL()
       
  2534 // ---------------------------------------------------------
       
  2535 //
       
  2536 TInt CRoapEng::MapStatusL()
       
  2537     {
       
  2538     LOGLIT( "CRoapEng::MapStatusL" )
       
  2539 
       
  2540     if ( iRoapStatus == ESuccess )
       
  2541         {
       
  2542         LOGLIT( "ROAP Status: success " )
       
  2543         return KErrNone;
       
  2544         }
       
  2545 
       
  2546     if ( iRoapStatus == ENotRegistered || iRoapStatus == EDeviceTimeError )
       
  2547         {
       
  2548         // Initiate registration protocol
       
  2549         LOG2( _L ( "Not Registered! Status: %d" ), iRoapStatus )
       
  2550 
       
  2551         if ( iRoapStatus == EDeviceTimeError )
       
  2552             {
       
  2553             iDeviceTimeError = ETrue;
       
  2554             }
       
  2555 
       
  2556         return KErrRoapNotRegistered;
       
  2557         }
       
  2558 
       
  2559     LOG2( _L ( "ROAP Error! Status: %d" ), iRoapStatus )
       
  2560 
       
  2561     switch ( iRoapStatus )
       
  2562         {
       
  2563         case EUnknownError:
       
  2564         case EAbort:
       
  2565             {
       
  2566             User::Leave( KErrRoapServer );
       
  2567             }
       
  2568         case ENotSupported:
       
  2569         case EAccessDenied:
       
  2570         case ENotFound:
       
  2571         case EMalformedRequest:
       
  2572         case EUnknownRequest:
       
  2573         case EUnknownCriticalExtension:
       
  2574         case EUnsupportedVersion:
       
  2575         case EUnsupportedAlgorithm:
       
  2576         case ESignatureError:
       
  2577         case EInvalidDCFHash:
       
  2578             {
       
  2579             User::Leave( KErrRoapServerFatal );
       
  2580             }
       
  2581         case ENoCertificateChain:
       
  2582         case EInvalidCertificateChain:
       
  2583         case ETrustedRootCertificateNotPresent:
       
  2584             {
       
  2585             User::Leave( KErrRoapDevice );
       
  2586             }
       
  2587         case EInvalidDomain:
       
  2588             {
       
  2589             User::Leave( KErrRoapInvalidDomain );
       
  2590             }
       
  2591         case EDomainFull:
       
  2592             {
       
  2593             User::Leave( KErrRoapDomainFull );
       
  2594             }
       
  2595         default:
       
  2596             {
       
  2597             User::Leave( KErrRoapUnsupported );
       
  2598             }
       
  2599         }
       
  2600     return KErrNone;
       
  2601     }
       
  2602 
       
  2603 // ---------------------------------------------------------
       
  2604 // CRoapEng::ValidateRiIdL()
       
  2605 //
       
  2606 // Validates that RI ID equals to public key hash of RI certificate
       
  2607 // ---------------------------------------------------------
       
  2608 //
       
  2609 TBool CRoapEng::ValidateRiIdL( TDesC8& aRiId, TDesC8& aCertBuf )
       
  2610     {
       
  2611     TBool valid = EFalse;
       
  2612     CX509Certificate* riCert = NULL;
       
  2613     CSHA1* hash = NULL;
       
  2614     HBufC8* publicKeyHash = NULL;
       
  2615 
       
  2616     riCert = CX509Certificate::NewLC( aCertBuf );
       
  2617 
       
  2618     // hash the SubjectPublicKeyInfo element
       
  2619     hash = CSHA1::NewL();
       
  2620     CleanupStack::PushL( hash );
       
  2621     hash->Hash( *riCert->DataElementEncoding(
       
  2622         CX509Certificate::ESubjectPublicKeyInfo ) );
       
  2623     publicKeyHash = hash->Final().AllocLC();
       
  2624 
       
  2625     if ( aRiId.Compare( *publicKeyHash ) == KErrNone )
       
  2626         {
       
  2627         valid = ETrue;
       
  2628         }
       
  2629 
       
  2630     CleanupStack::PopAndDestroy( publicKeyHash );
       
  2631     CleanupStack::PopAndDestroy( hash );
       
  2632     CleanupStack::PopAndDestroy( riCert );
       
  2633 
       
  2634     return valid;
       
  2635     }
       
  2636 
       
  2637 // ---------------------------------------------------------
       
  2638 // CRoapEng::UpdateTransactionTrackingStatusL()
       
  2639 //
       
  2640 // Update the status of transaction tracking variable
       
  2641 // ---------------------------------------------------------
       
  2642 //
       
  2643 void CRoapEng::UpdateTransactionTrackingStatusL()
       
  2644     {
       
  2645     TInt value = KErrNone;
       
  2646     CRepository* repository = CRepository::NewL( KCRUidDRMSettings );
       
  2647     repository->Get( KDRMSettingsTransactionTracking, value );
       
  2648     delete repository;
       
  2649     iTransStatus = value ? EAllowed : EForbidden;
       
  2650     }
       
  2651 
       
  2652 // ---------------------------------------------------------
       
  2653 // CRoapEng::CreateDeviceIdHashArrayL()
       
  2654 // ---------------------------------------------------------
       
  2655 //
       
  2656 TInt CRoapEng::CreateDeviceIdHashArrayL( RPointerArray<TDesC8>& aIdArray )
       
  2657     {
       
  2658     TInt err( KErrNone );
       
  2659     RPointerArray<HBufC8> certChain;
       
  2660     CSHA1* hasher = NULL;
       
  2661     HBufC8* publicKey = NULL;
       
  2662     CX509Certificate* cert = NULL;
       
  2663 
       
  2664     err = iStorageClient->GetDeviceCertificateChainL( certChain );
       
  2665 
       
  2666     CleanupResetAndDestroyPushL( certChain );
       
  2667 
       
  2668     hasher = CSHA1::NewL();
       
  2669     CleanupStack::PushL( hasher );
       
  2670     // take the hash of device certificate
       
  2671     if (certChain.Count()<=0)
       
  2672         {
       
  2673         LOGLIT( "Could get Device id Hash!!!" )
       
  2674         User::Leave( KErrGeneral );
       
  2675         }
       
  2676     cert = CX509Certificate::NewL( *certChain[0] );
       
  2677     CleanupStack::PushL( cert );
       
  2678     publicKey = cert->DataElementEncoding(
       
  2679         CX509Certificate::ESubjectPublicKeyInfo )->AllocLC();
       
  2680 
       
  2681     hasher->Hash( *publicKey );
       
  2682 
       
  2683     HBufC8 *elem( hasher->Final().AllocLC() );
       
  2684     aIdArray.AppendL( elem );
       
  2685     CleanupStack::Pop( elem );
       
  2686 
       
  2687     CleanupStack::PopAndDestroy( publicKey );
       
  2688     CleanupStack::PopAndDestroy( cert );
       
  2689 
       
  2690     CleanupStack::PopAndDestroy( hasher );
       
  2691     CleanupStack::PopAndDestroy( &certChain );
       
  2692     return err;
       
  2693     }
       
  2694 
       
  2695 // End of file