omadrm/drmengine/roap/src/MeteringReportReq.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:  Class representing metering report request
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32std.h>
       
    22 #include "base64.h"
       
    23 #include "MeteringReportReq.h"
       
    24 #include "RoapLog.h"
       
    25 
       
    26 using namespace Roap;
       
    27 
       
    28 // LOCAL CONSTANTS AND MACROS
       
    29 // XML tag related literals
       
    30 // Warning: these literals are very fragile in respect to XML canonicalisation.
       
    31 _LIT8(KReqHeader, "<roap:meteringReportSubmit xmlns:roap=\"urn:oma:bac:dldrm:roap-1.0\"");
       
    32 _LIT8(KReqNonceTrigger, " triggerNonce=\"");
       
    33 _LIT8(KReqNonceTriggerEnd, "\"");
       
    34 _LIT8(KReqHeaderEnd, ">");
       
    35 _LIT8(KReqDeviceId, "<deviceID><keyIdentifier xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"roap:X509SPKIHash\"><hash>");
       
    36 _LIT8(KReqDeviceIdEnd, "</hash></keyIdentifier></deviceID>");
       
    37 _LIT8(KReqRiId, "<riID><keyIdentifier xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"roap:X509SPKIHash\"><hash>");
       
    38 _LIT8(KReqRiIdEnd, "</hash></keyIdentifier></riID>");
       
    39 _LIT8(KReqNonce, "<nonce>");
       
    40 _LIT8(KReqNonceEnd, "</nonce>");
       
    41 _LIT8(KReqTime, "<time>");
       
    42 _LIT8(KReqTimeEnd, "</time>");
       
    43 _LIT8(KReqMeteringReport, "<meteringReport>");
       
    44 
       
    45 _LIT8(KReqReportHeader,
       
    46 "<encryptedMeteringReport>\
       
    47 <xenc:EncryptedData xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\"\
       
    48  Type=\"http://www.w3.org/2001/04/xmlenc#Content\">\
       
    49 <xenc:EncryptionMethod\
       
    50  Algorithm=\"http://www.w3.org/2001/04/xmlenc#aes128-cbc\">\
       
    51 </xenc:EncryptionMethod>");
       
    52 
       
    53 _LIT8(KReqKeyInfo, "<ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\
       
    54 <ds:RetrievalMethod URI=\"#K_MEK_and_K_MAC\"></ds:RetrievalMethod>\
       
    55 </ds:KeyInfo>");
       
    56 
       
    57 _LIT8(KReqCipherDataStart, "<xenc:CipherData><xenc:CipherValue>");
       
    58 _LIT8(KReqCipherDataEnd, "</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></encryptedMeteringReport>");
       
    59 
       
    60 _LIT8(KReqEncKeyAndMethod, "<encKey Id=\"K_MEK_and_K_MAC\"><xenc:EncryptionMethod\
       
    61  xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\" Algorithm=\"" );
       
    62 
       
    63 _LIT8(KReqEncKeyAndMethodAfterAlgorithm, "\"></xenc:EncryptionMethod>");
       
    64 
       
    65 _LIT8(KReqEncKeyInfoStart, "<ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">");
       
    66 
       
    67 // Note the two versions below are because of different namespace
       
    68 // normalisation of element roap:X509SPKIHash on canonicalisation of
       
    69 // whole request to be signed and on canonicalisation of element 
       
    70 // <meteringReport> to be MAC calculated.
       
    71 // when changing one of these another one must be cahnges too.
       
    72 //
       
    73 // This version is used when canonicalisation is performed over
       
    74 // <roap:meteringReportSubmit>
       
    75 //
       
    76 _LIT8(KReqRoapX509AndHash, "<roap:X509SPKIHash><hash>");
       
    77 //
       
    78 //
       
    79 // This version is used when canonicalisation is taken over <meteringReport>
       
    80 // (on MAC calculation)
       
    81 //
       
    82 _LIT8(KReqRoapX509AndHashNs, "<roap:X509SPKIHash xmlns:roap=\"urn:oma:bac:dldrm:roap-1.0\"><hash>");
       
    83 
       
    84 
       
    85 _LIT8(KReqEncKeyInfoEnd, "</hash></roap:X509SPKIHash></ds:KeyInfo>\
       
    86 <xenc:CipherData xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\"><xenc:CipherValue>");
       
    87 
       
    88 _LIT8(KReqCipherValueEnd, "</xenc:CipherValue></xenc:CipherData></encKey>");
       
    89 _LIT8(KReqMacStart, "<mac>");
       
    90 _LIT8(KReqMacEnd, "</mac>");
       
    91 _LIT8(KReqReportHeaderEnd, "</meteringReport>");
       
    92 _LIT8(KReqCertChain, "<certificateChain>");
       
    93 _LIT8(KReqCert, "<certificate>");
       
    94 _LIT8(KReqCertEnd, "</certificate>");
       
    95 _LIT8(KReqCertChainEnd, "</certificateChain>");
       
    96 _LIT8(KReqSig, "<signature>");
       
    97 _LIT8(KReqSigEnd, "</signature></roap:meteringReportSubmit>");
       
    98 // literals for key transport scheme
       
    99 _LIT8( KOmaKdf, "http://www.rsasecurity.com/rsalabs/pkcs/schemas/pkcs-1#rsaes-kem-kdf2-kw-aes128");
       
   100 _LIT8( KCmlaIp1, "http://www.cm-la.com/tech/cmlaip/cmlaip#cmlaip-1");
       
   101 // ============================ LOCAL FUNCTIONS ===============================
       
   102 
       
   103 // ----------------------------------------------------------------------------
       
   104 // MeteringReportElementAsTextL
       
   105 //
       
   106 // write content of to given flat buffer 
       
   107 // Used from MessageAsXmlL and from InsertMacL
       
   108 // Note content depends on value of 
       
   109 // ----------------------------------------------------------------------------
       
   110 LOCAL_C inline void MeteringReportElementAsTextL(
       
   111     CBufFlat*& aBuf,
       
   112     const Roap::CMeteringReportReq& aReq
       
   113     )
       
   114     {
       
   115     Roap::CRoapMessage::BufAppendL( aBuf, KReqMeteringReport );
       
   116     Roap::CRoapMessage::BufAppendL( aBuf, KReqReportHeader );
       
   117 
       
   118     Roap::CRoapMessage::BufAppendL( aBuf, KReqKeyInfo );
       
   119 
       
   120     Roap::CRoapMessage::BufAppendL( aBuf, KReqCipherDataStart );
       
   121 
       
   122     // actual encrypted metering data
       
   123     if ( aReq.iCipherValue )
       
   124         {
       
   125         Roap::CRoapMessage::BufAppendBase64L( aBuf, *aReq.iCipherValue );
       
   126         }
       
   127 
       
   128     Roap::CRoapMessage::BufAppendL( aBuf, KReqCipherDataEnd );
       
   129 
       
   130     Roap::CRoapMessage::BufAppendL( aBuf, KReqEncKeyAndMethod );
       
   131 
       
   132     // Select KDF algorithm in use
       
   133     if ( aReq.iAlgorithmInUse == ECmlaIp1 )
       
   134         {
       
   135         Roap::CRoapMessage::BufAppendL( aBuf, KCmlaIp1 );
       
   136         }
       
   137     else if ( aReq.iAlgorithmInUse == EOma )
       
   138         {
       
   139         Roap::CRoapMessage::BufAppendL( aBuf, KOmaKdf );
       
   140         }
       
   141     else
       
   142         {
       
   143         User::Leave( KErrNotSupported );
       
   144         }
       
   145     Roap::CRoapMessage::BufAppendL( aBuf, KReqEncKeyAndMethodAfterAlgorithm );
       
   146     Roap::CRoapMessage::BufAppendL( aBuf, KReqEncKeyInfoStart );
       
   147 
       
   148     if ( aReq.iMac )
       
   149         {
       
   150         // used as part of roap:Meteringreport submit
       
   151         // so namespace ROAP already defined in container element
       
   152         Roap::CRoapMessage::BufAppendL( aBuf, KReqRoapX509AndHash );
       
   153         }
       
   154     else
       
   155         {
       
   156         // used in mac calculation 
       
   157         // canonical form requires namespace definition for namespace roap
       
   158         Roap::CRoapMessage::BufAppendL( aBuf, KReqRoapX509AndHashNs );
       
   159         }
       
   160 
       
   161     // Insert 128-bit encrypted encryption key PKI hash
       
   162     Roap::CRoapMessage::BufAppendBase64L( aBuf, aReq.iEncKeyHash );
       
   163 
       
   164 
       
   165     Roap::CRoapMessage::BufAppendL( aBuf, KReqEncKeyInfoEnd );
       
   166 
       
   167     // key wrapping info
       
   168     Roap::CRoapMessage::BufAppendBase64L( aBuf, *aReq.iEncryptedMekAndMak );
       
   169 
       
   170     Roap::CRoapMessage::BufAppendL( aBuf, KReqCipherValueEnd );    
       
   171 
       
   172     // Insert 128-bit encrypted MAC value
       
   173     if ( aReq.iMac )
       
   174         {
       
   175         Roap::CRoapMessage::BufAppendL( aBuf, KReqMacStart );
       
   176         Roap::CRoapMessage::BufAppendBase64L( aBuf, *aReq.iMac );
       
   177         Roap::CRoapMessage::BufAppendL( aBuf, KReqMacEnd );
       
   178         }
       
   179     Roap::CRoapMessage::BufAppendL( aBuf, KReqReportHeaderEnd );
       
   180     }
       
   181 
       
   182 // -----------------------------------------------------------------------------
       
   183 // CalculateMacL
       
   184 // -----------------------------------------------------------------------------
       
   185 //
       
   186 LOCAL_C HBufC8* CalculateMacL(const TDesC8& aElement, const TDesC8& aMacKey )
       
   187     {
       
   188 
       
   189     LOG( _L8( "CalculateMacL" ) );
       
   190     LOG( _L8( "aMacKey" ) );
       
   191     LOGHEX( aMacKey.Ptr(), aMacKey.Length() );
       
   192     LOG( _L8( "aElement" ) );
       
   193     LOGHEX( aElement.Ptr(), aElement.Length() );
       
   194     if( !aMacKey.Length() || !aElement.Length() )
       
   195         {
       
   196         User::Leave(KErrArgument);
       
   197         }
       
   198 
       
   199     CHMAC* hMac = NULL;
       
   200     CSHA1* sha = NULL;
       
   201     TPtrC8 hmac_value( KNullDesC8 );
       
   202     TPtrC8 sha1_value( KNullDesC8 );
       
   203     HBufC8* macValue = NULL;
       
   204 
       
   205     sha = CSHA1::NewL();
       
   206     CleanupStack::PushL( sha );
       
   207     hMac = CHMAC::NewL( aMacKey, sha );
       
   208     CleanupStack::Pop( sha ); // sha is now owned by hMac
       
   209     CleanupStack::PushL( hMac );
       
   210     hMac->Update( aElement );
       
   211     hmac_value.Set( hMac->Final() );
       
   212 
       
   213     macValue = hmac_value.AllocL();
       
   214     LOG( _L8( "macValue" ) );
       
   215     LOGHEX( macValue->Ptr(), macValue->Length() );
       
   216 
       
   217     CleanupStack::PopAndDestroy( hMac );
       
   218     return macValue;
       
   219     }
       
   220 
       
   221 
       
   222 // ============================ MEMBER FUNCTIONS ===============================
       
   223 
       
   224 // -----------------------------------------------------------------------------
       
   225 // CRightsReq::CRightsReq
       
   226 // C++ default constructor can NOT contain any code, that
       
   227 // might leave.
       
   228 // -----------------------------------------------------------------------------
       
   229 //
       
   230 CMeteringReportReq::CMeteringReportReq():
       
   231     iNonce(NULL),
       
   232     iReportNonce(NULL),
       
   233     iSignature(NULL),
       
   234     iCipherValue(NULL),
       
   235     iMac(NULL),
       
   236     iTriggerNonce(NULL)
       
   237     {
       
   238     }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 // CRightsReq::ConstructL
       
   242 // Symbian 2nd phase constructor can leave.
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 void CMeteringReportReq::ConstructL()
       
   246     {
       
   247     iTime.UniversalTime();
       
   248     }
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // CRightsReq::NewL
       
   252 // Two-phased constructor.
       
   253 // -----------------------------------------------------------------------------
       
   254 //
       
   255 CMeteringReportReq* CMeteringReportReq::NewL()
       
   256     {
       
   257     CMeteringReportReq* self = new( ELeave ) CMeteringReportReq;
       
   258 
       
   259     CleanupStack::PushL( self );
       
   260     self->ConstructL();
       
   261     CleanupStack::Pop( self );
       
   262 
       
   263     return self;
       
   264     }
       
   265 
       
   266 
       
   267 // Destructor
       
   268 CMeteringReportReq::~CMeteringReportReq()
       
   269     {
       
   270     if ( iCertificateChain.Count() )
       
   271         {
       
   272         iCertificateChain.ResetAndDestroy();
       
   273         }
       
   274     delete iSignature;
       
   275     delete iTriggerNonce;
       
   276     delete iCipherValue;
       
   277     delete iEncryptedMekAndMak;
       
   278     delete iMac;
       
   279     }
       
   280 
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // CRightsReq::MessageAsXmlL
       
   284 // Gives XML representation of meteringreport request
       
   285 // (other items were commented in a header).
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 HBufC8* CMeteringReportReq::MessageAsXmlL(void)
       
   289     {
       
   290     HBufC8* r( NULL );
       
   291     CBufFlat* b( CBufFlat::NewL( 128 ) );
       
   292     CleanupStack::PushL( b );
       
   293     b->InsertL( 0, KReqHeader );
       
   294     if ( iTriggerNonce )
       
   295         {
       
   296         BufAppendL( b, KReqNonceTrigger );
       
   297         BufAppendL( b, *iTriggerNonce );
       
   298         BufAppendL( b, KReqNonceTriggerEnd );
       
   299         }
       
   300     BufAppendL( b, KReqHeaderEnd );
       
   301 
       
   302     BufAppendL( b, KReqDeviceId );
       
   303     BufAppendBase64L( b, iDeviceId );
       
   304     BufAppendL( b, KReqDeviceIdEnd );
       
   305 
       
   306     BufAppendL( b, KReqRiId );
       
   307     BufAppendBase64L( b, iRiId );
       
   308     BufAppendL( b, KReqRiIdEnd );
       
   309 
       
   310     BufAppendL( b, KReqNonce );
       
   311     BufAppendBase64L( b, iNonce );
       
   312     BufAppendL( b, KReqNonceEnd );
       
   313 
       
   314     BufAppendL( b, KReqTime );
       
   315     BufAppendTimeL( b, iTime );
       
   316     BufAppendL( b, KReqTimeEnd );
       
   317 
       
   318     MeteringReportElementAsTextL( b, *this );
       
   319 
       
   320     if ( iCertificateChain.Count() > 0 )
       
   321         {
       
   322         BufAppendL( b, KReqCertChain );
       
   323         for ( TInt i( 0 ); i < iCertificateChain.Count(); i++ )
       
   324             {
       
   325             BufAppendL( b, KReqCert );
       
   326             BufAppendBase64L( b, *iCertificateChain[ i ] );
       
   327             BufAppendL( b, KReqCertEnd );
       
   328             }
       
   329         BufAppendL( b, KReqCertChainEnd );
       
   330         }
       
   331 
       
   332     BufAppendL(b, KReqSig);
       
   333     BufAppendL(b, KReqSigEnd);
       
   334 
       
   335     r = b->Ptr( 0 ).AllocL();
       
   336     CleanupStack::PopAndDestroy( b );
       
   337     return r;
       
   338     }
       
   339 
       
   340 // -----------------------------------------------------------------------------
       
   341 // CMeteringReportReq::InsertMacL( const TDesC8& aMac )
       
   342 // Calculate MAC -value over <encryptedMeteringReport>
       
   343 // (other items were commented in a header).
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 void CMeteringReportReq::InsertMacL( const TDesC8& aMacKey )
       
   347     {
       
   348     CBufFlat* b( CBufFlat::NewL( 128 ) );
       
   349     CleanupStack::PushL( b );
       
   350 
       
   351 
       
   352     MeteringReportElementAsTextL( b, *this );
       
   353 
       
   354     // Calculate MAC -value over <encryptedMeteringReport>
       
   355     // without the actual <mac> -element
       
   356 
       
   357     iMac = CalculateMacL( b->Ptr( 0 ), aMacKey );
       
   358     CleanupStack::PopAndDestroy( b );
       
   359     return;
       
   360     }
       
   361 
       
   362 //  End of File