omaprovisioning/provisioning/ProvisioningEngine/Src/CWPPushMessage.cpp
changeset 0 b497e44ab2fc
child 65 5cc2995847ea
equal deleted inserted replaced
-1:000000000000 0:b497e44ab2fc
       
     1 /*
       
     2 * Copyright (c) 2002 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:  Helps in saving/loading a push message.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDE FILES
       
    20 #include <e32base.h>
       
    21 #include <msvstore.h>
       
    22 #include <hash.h>
       
    23 #include <chttpresponse.h>
       
    24 #include <centralrepository.h>
       
    25 #include "ProvisioningVariant.hrh"
       
    26 #include "CWPPushMessage.h"
       
    27 #include "ProvisioningDebug.h"
       
    28 #include "ProvisioningUIDs.h"
       
    29 #include "CWPEngine.pan"
       
    30 #include "ProvisioningInternalCRKeys.h"
       
    31 
       
    32 // CONSTANTS
       
    33 
       
    34 /// Short integers must be masked with this to get real number
       
    35 const TUint KShortIntegerMask = 0x7f;
       
    36 
       
    37 /// In q-values if the number is above this number, there are more bytes.
       
    38 const TUint KQValueContinuation = 0x80;
       
    39 
       
    40 /// Quotes strings start with this constant.
       
    41 const TUint KQuotedStringStart = 34;
       
    42 
       
    43 /// Quotes strings start with this constant.
       
    44 const TUint KQuotedTextStringStart = 127;
       
    45 
       
    46 /// Maximum length of a long integer.
       
    47 const TUint KMaxLongIntegerLength = 30;
       
    48 
       
    49 /// Types of coding a value in a parameter
       
    50 enum TParameterCodingType {
       
    51     EQValue,
       
    52     EWellKnownCharset,
       
    53     EVersionValue,
       
    54     EIntegerValue,
       
    55     ETextString,
       
    56     EFieldName,
       
    57     EShortInteger,
       
    58     EConstrainedEncoding,
       
    59     EDeltaSecondsValue,
       
    60     ENoValue,
       
    61     ETextValue,
       
    62     EDateValue
       
    63     };
       
    64 
       
    65 /// Well-known parameter assignments and their mappings to value types
       
    66 /// (WAP-230-WSP-20010705-a, table 38)
       
    67 const TParameterCodingType KParameterTypes[] = 
       
    68     {
       
    69     EQValue,
       
    70     EWellKnownCharset,
       
    71     EVersionValue,
       
    72     EIntegerValue,
       
    73     ENoValue,
       
    74     ETextString,
       
    75     ETextString,
       
    76     EFieldName,
       
    77     EShortInteger,
       
    78     EConstrainedEncoding,
       
    79     ETextString,
       
    80     ETextString,
       
    81     ETextString,
       
    82     ETextString,
       
    83     EDeltaSecondsValue,
       
    84     ETextString,
       
    85     ENoValue,
       
    86     EShortInteger,
       
    87     ETextValue,
       
    88     EDateValue,
       
    89     EDateValue,
       
    90     EDateValue,
       
    91     EIntegerValue,
       
    92     ETextValue,
       
    93     ETextValue,
       
    94     ETextValue,
       
    95     ETextValue,
       
    96     ETextValue,
       
    97     ETextValue,
       
    98     ETextValue
       
    99     };
       
   100 
       
   101 /// Date-values are seconds from this date
       
   102 _LIT( KDateValueStart, "19700101:000000.000000" );
       
   103 
       
   104 /// WSP constant for field SEC
       
   105 const TInt KWSPHeaderSEC = 0x11;
       
   106 
       
   107 /// WSP constant for field MAC
       
   108 const TInt KWSPHeaderMAC = 0x12;
       
   109 
       
   110 /// Number of BCD digits in byte
       
   111 const TInt KNumDigitsInByte = 2;
       
   112 
       
   113 /// Number of bits in half-byte
       
   114 const TInt KNumBitsInNibble = 4;
       
   115 
       
   116 /// Ascii code for zero
       
   117 const TUint8 KZero = '0';
       
   118 
       
   119 /// Padding half-byte
       
   120 const TUint8 KPadNibble = 0xf;
       
   121 
       
   122 /// First nibble
       
   123 const TUint8 KFirstNibble = 0x1;
       
   124 
       
   125 /// Parity bit number in first nibble
       
   126 const TUint KParityBitNum = 3;
       
   127 
       
   128 /// Content type code for OMA Provisioning messages
       
   129 const TUint8 KContentType = 0xb6;
       
   130 
       
   131 /// Provisioning message format version when stored in Messaging Store
       
   132 const TInt KProvisioningMsgVersion = 1;
       
   133 
       
   134 // ============================ MEMBER FUNCTIONS ===============================
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CWPPushMessage::CWPPushMessage
       
   138 // C++ default constructor can NOT contain any code, that
       
   139 // might leave.
       
   140 // -----------------------------------------------------------------------------
       
   141 //
       
   142 CWPPushMessage::CWPPushMessage()
       
   143 : iInitiator( KNullDesC8 ), iSEC( KSECNONE )
       
   144     {
       
   145     }
       
   146 
       
   147 // -----------------------------------------------------------------------------
       
   148 // CWPPushMessage::ConstructL
       
   149 // Symbian 2nd phase constructor can leave.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 void CWPPushMessage::ConstructL()
       
   153     {
       
   154     iHeader = CHTTPResponse::NewL();
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CWPPushMessage::NewL
       
   159 // Two-phased constructor.
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 EXPORT_C CWPPushMessage* CWPPushMessage::NewL()
       
   163     {
       
   164     CWPPushMessage* self = NewLC();
       
   165     CleanupStack::Pop();
       
   166     
       
   167     return self;
       
   168     }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CWPPushMessage::NewLC
       
   172 // Two-phased constructor.
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 EXPORT_C CWPPushMessage* CWPPushMessage::NewLC()
       
   176     {
       
   177     CWPPushMessage* self = new( ELeave ) CWPPushMessage;
       
   178     
       
   179     CleanupStack::PushL( self );
       
   180     self->ConstructL();
       
   181     
       
   182     return self;
       
   183     }
       
   184 
       
   185 // Destructor
       
   186 CWPPushMessage::~CWPPushMessage()
       
   187     {
       
   188     delete iBody;
       
   189     delete iHeader;
       
   190     delete iOriginator;
       
   191     }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CWPPushMessage::StoreL
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 EXPORT_C void CWPPushMessage::StoreL( CMsvStore& aStore ) const
       
   198     {
       
   199     TUid uid;
       
   200     uid.iUid = KProvisioningMessageStreamUid;
       
   201 
       
   202     aStore.Remove( uid );
       
   203 
       
   204     RMsvWriteStream stream;
       
   205     stream.AssignLC( aStore, uid );
       
   206     ExternalizeL( stream );
       
   207     CleanupStack::PopAndDestroy(); // stream
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CWPPushMessage::RestoreL
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 EXPORT_C void CWPPushMessage::RestoreL( CMsvStore& aStore )
       
   215     {
       
   216     RMsvReadStream stream;
       
   217     stream.OpenLC( aStore, TUid::Uid( KProvisioningMessageStreamUid ) );
       
   218     InternalizeL( stream );
       
   219     CleanupStack::PopAndDestroy(); // stream
       
   220 
       
   221     ParseHeaderL();
       
   222     }
       
   223 
       
   224 // -----------------------------------------------------------------------------
       
   225 // CWPPushMessage::ExternalizeL
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 EXPORT_C void CWPPushMessage::ExternalizeL( RWriteStream& aStream ) const
       
   229     {
       
   230     // Save version
       
   231     aStream.WriteInt32L( KProvisioningMsgVersion );
       
   232 
       
   233     // Save the header
       
   234     aStream.WriteInt32L( iHeader->Response().Length() );
       
   235     aStream << iHeader->Response();
       
   236     aStream.WriteInt8L( iAuthenticated );
       
   237     aStream.WriteInt8L( iSaved );
       
   238 
       
   239     // Save the body
       
   240     aStream.WriteInt32L( iBody->Length() );
       
   241     aStream << *iBody;
       
   242 
       
   243     // The sender
       
   244     if( iOriginator )
       
   245         {
       
   246         aStream.WriteInt32L( iOriginator->Length() );
       
   247         aStream << *iOriginator;
       
   248         }
       
   249     else
       
   250         {
       
   251         aStream.WriteInt32L( KNullDesC8().Length() );
       
   252         }
       
   253 
       
   254     aStream.CommitL();
       
   255     }
       
   256 
       
   257 // -----------------------------------------------------------------------------
       
   258 // CWPPushMessage::InternalizeL
       
   259 // -----------------------------------------------------------------------------
       
   260 //
       
   261 EXPORT_C void CWPPushMessage::InternalizeL( RReadStream& aStream )
       
   262     {
       
   263     // Restore the header
       
   264     TInt version( aStream.ReadInt32L() );
       
   265 
       
   266     TInt length( aStream.ReadInt32L() );
       
   267     HBufC8* header = HBufC8::NewLC( aStream, length );
       
   268     iAuthenticated = aStream.ReadInt8L();
       
   269     iSaved = aStream.ReadInt8L();
       
   270 
       
   271     // Restore the body
       
   272     length = aStream.ReadInt32L();
       
   273     HBufC8* body = HBufC8::NewL( aStream, length );
       
   274 
       
   275     // Store header and body
       
   276     CleanupStack::Pop(); // header
       
   277     Set( header, body );
       
   278 
       
   279     if( version == KProvisioningMsgVersion )
       
   280         {
       
   281         length = aStream.ReadInt32L();
       
   282         if( length > 0 )
       
   283             {
       
   284             delete iOriginator;
       
   285             iOriginator = NULL;
       
   286             iOriginator = HBufC8::NewL( aStream, length );
       
   287             }
       
   288         }
       
   289     }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CWPPushMessage::SetL
       
   293 // -----------------------------------------------------------------------------
       
   294 //
       
   295 EXPORT_C void CWPPushMessage::SetL( const TDesC8& aHeader, const TDesC8& aBody )
       
   296     {
       
   297     HBufC8* header = aHeader.AllocLC();
       
   298     HBufC8* body = aBody.AllocL();
       
   299     CleanupStack::Pop(); // header
       
   300     Set( header, body );
       
   301     }
       
   302 
       
   303 
       
   304 // -----------------------------------------------------------------------------
       
   305 // CWPPushMessage::Set
       
   306 // -----------------------------------------------------------------------------
       
   307 //
       
   308 EXPORT_C void CWPPushMessage::Set( HBufC8* aHeader, HBufC8* aBody )
       
   309     {
       
   310     __ASSERT_DEBUG( aHeader && aBody, Panic( EWPNullMessage ) );
       
   311     iHeader->AddResponse( aHeader );
       
   312 
       
   313     delete iBody;
       
   314     iBody = aBody;
       
   315     }
       
   316 
       
   317 
       
   318 // -----------------------------------------------------------------------------
       
   319 // CWPPushMessage::SetOriginatorL
       
   320 // -----------------------------------------------------------------------------
       
   321 //
       
   322 EXPORT_C void CWPPushMessage::SetOriginatorL( const TDesC8& aOrig )
       
   323     {
       
   324     HBufC8* orig = aOrig.AllocL();
       
   325     delete iOriginator;
       
   326     iOriginator = orig;
       
   327     }
       
   328 
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // CWPPushMessage::Header
       
   332 // -----------------------------------------------------------------------------
       
   333 //
       
   334 EXPORT_C const TDesC8& CWPPushMessage::Header() const
       
   335     {
       
   336     if( iHeader )
       
   337         {
       
   338         return iHeader->Response();
       
   339         }
       
   340     else
       
   341         {
       
   342         return KNullDesC8;
       
   343         }
       
   344     }
       
   345 
       
   346 // -----------------------------------------------------------------------------
       
   347 // CWPPushMessage::Body
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 EXPORT_C const TDesC8& CWPPushMessage::Body() const
       
   351     {
       
   352     if( iBody )
       
   353         {
       
   354         return *iBody;
       
   355         }
       
   356     else
       
   357         {
       
   358         return KNullDesC8;
       
   359         }
       
   360     }
       
   361 
       
   362 // -----------------------------------------------------------------------------
       
   363 // CWPPushMessage::Originator
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 EXPORT_C const TDesC8& CWPPushMessage::Originator() const
       
   367     {
       
   368     if( iOriginator )
       
   369         {
       
   370         return *iOriginator;
       
   371         }
       
   372     else
       
   373         {
       
   374         return KNullDesC8;
       
   375         }
       
   376     }
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // CWPPushMessage::SetAuthenticated
       
   380 // -----------------------------------------------------------------------------
       
   381 //
       
   382 EXPORT_C void CWPPushMessage::SetAuthenticated( TBool aAuthenticated )
       
   383     {
       
   384     iAuthenticated = aAuthenticated;
       
   385     }
       
   386 
       
   387 // -----------------------------------------------------------------------------
       
   388 // CWPPushMessage::Authenticated
       
   389 // -----------------------------------------------------------------------------
       
   390 //
       
   391 EXPORT_C TBool CWPPushMessage::Authenticated() const
       
   392     {
       
   393     return iAuthenticated;
       
   394     }
       
   395 
       
   396 // -----------------------------------------------------------------------------
       
   397 // CWPPushMessage::SetSaved
       
   398 // -----------------------------------------------------------------------------
       
   399 //
       
   400 EXPORT_C void CWPPushMessage::SetSaved( TBool aSaved )
       
   401     {
       
   402     iSaved = aSaved;
       
   403     }
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // CWPPushMessage::Saved
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 EXPORT_C TBool CWPPushMessage::Saved() const
       
   410     {
       
   411     return iSaved;
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CWPPushMessage::InitiatorURI
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 EXPORT_C const TDesC8& CWPPushMessage::InitiatorURI() const
       
   419     {
       
   420     return iInitiator;
       
   421     }
       
   422 
       
   423 // -----------------------------------------------------------------------------
       
   424 // CWPPushMessage::MAC
       
   425 // -----------------------------------------------------------------------------
       
   426 //
       
   427 EXPORT_C const TDesC8& CWPPushMessage::MAC() const
       
   428     {
       
   429     return iMAC;
       
   430     }
       
   431 
       
   432 // -----------------------------------------------------------------------------
       
   433 // CWPPushMessage::SEC
       
   434 // -----------------------------------------------------------------------------
       
   435 //
       
   436 EXPORT_C TUint CWPPushMessage::SEC() const
       
   437     {
       
   438     return iSEC;
       
   439     }
       
   440 
       
   441 // -----------------------------------------------------------------------------
       
   442 // CWPPushMessage::PushFlag
       
   443 // -----------------------------------------------------------------------------
       
   444 //
       
   445 EXPORT_C TInt CWPPushMessage::PushFlag() const
       
   446     {
       
   447     return iPushFlag;
       
   448     }
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // CWPPushMessage::ParseHeader
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 EXPORT_C void CWPPushMessage::ParseHeaderL()
       
   455     {
       
   456     // CHTTPResponse panicks if it is used for parsing a zero-length 
       
   457     // descriptor.
       
   458     if( iHeader->Response().Length() > 0 )
       
   459         {
       
   460         // We use lexer for safety.
       
   461         TLex8 contentType( ContentTypeHeader( *iHeader ) );
       
   462         if( !contentType.Eos() )
       
   463             {
       
   464             ParseContentType( contentType );
       
   465             }
       
   466         
       
   467         TLex8 initiatorURI( InitiatorURIHeader( *iHeader ) );
       
   468         if( !initiatorURI.Eos() )
       
   469             {
       
   470             ParseInitiatorURI( initiatorURI );
       
   471             }
       
   472         
       
   473         TLex8 pushFlag( PushFlagHeader( *iHeader ) );
       
   474         if( !pushFlag.Eos() )
       
   475             {
       
   476             ParsePushFlag( pushFlag );
       
   477             }
       
   478         }
       
   479     }
       
   480 
       
   481 
       
   482 // -----------------------------------------------------------------------------
       
   483 // CWPPushMessage::ParseInitiatorURI
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 void CWPPushMessage::ParseInitiatorURI( TLex8& aPointer )
       
   487     {
       
   488     iInitiator.Set( GetTextString( aPointer ) );
       
   489     }
       
   490 
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 // CWPPushMessage::ParsePushFlag
       
   494 // -----------------------------------------------------------------------------
       
   495 //
       
   496 void CWPPushMessage::ParsePushFlag( TLex8& aPointer )
       
   497     {
       
   498     TInt64 pushFlag( GetIntegerValue( aPointer ) );
       
   499 
       
   500     iPushFlag = I64LOW(pushFlag);
       
   501     }
       
   502 
       
   503 
       
   504 // -----------------------------------------------------------------------------
       
   505 // CWPPushMessage::ParseContentType
       
   506 // -----------------------------------------------------------------------------
       
   507 //
       
   508 void CWPPushMessage::ParseContentType( TLex8& aPointer )
       
   509     {
       
   510     // Go through the whole content type header.
       
   511     while( !aPointer.Eos() )
       
   512         {
       
   513         // Each parameter might be well-known (integer) or unknown (text)
       
   514         if( IsIntegerValue( aPointer ) )
       
   515             {
       
   516             // For well-known parameters, the token is an integer value
       
   517             TUint paramToken( I64LOW( GetIntegerValue( aPointer ) ) );
       
   518 
       
   519             // These are filled with results from parsing.
       
   520             TInt resultInteger( 0 );
       
   521             TPtrC8 resultString;
       
   522             
       
   523             // Make sure paramToken fits into KParameterTypes table
       
   524             if( paramToken 
       
   525                 < sizeof(KParameterTypes)/sizeof(TParameterCodingType))
       
   526                 {
       
   527                 // Get the coding and use it to determine how we should decode 
       
   528                 // the next parameter value. We actually ignore all results 
       
   529                 // except short integer (SEC) and text-value (MAC), but the 
       
   530                 // rest of the parameters have to be parsed anyway.
       
   531                 TParameterCodingType coding( KParameterTypes[paramToken] );
       
   532 
       
   533                 switch( coding )
       
   534                     {
       
   535                     case EQValue:
       
   536                         GetQValue( aPointer );
       
   537                         break;
       
   538 
       
   539                     case EWellKnownCharset:
       
   540                         GetWellKnownCharset( aPointer );
       
   541                         break;
       
   542 
       
   543                     case EVersionValue:
       
   544                         GetVersionValue( aPointer );
       
   545                         break;
       
   546 
       
   547                     case EIntegerValue:
       
   548                         GetIntegerValue( aPointer );
       
   549                         break;
       
   550 
       
   551                     case ETextString:
       
   552                         GetTextString( aPointer );
       
   553                         break;
       
   554 
       
   555                     case EFieldName:
       
   556                         GetFieldName( aPointer );
       
   557                         break;
       
   558 
       
   559                     case EShortInteger:
       
   560                         resultInteger = GetShortInteger( aPointer );
       
   561                         break;
       
   562 
       
   563                     case EConstrainedEncoding:
       
   564                         GetConstrainedEncoding( aPointer );
       
   565                         break;
       
   566 
       
   567                     case EDeltaSecondsValue:
       
   568                         GetDeltaSecondsValue( aPointer );
       
   569                         break;
       
   570 
       
   571                     case ENoValue:
       
   572                         GetNoValue( aPointer );
       
   573                         break;
       
   574 
       
   575                     case ETextValue:
       
   576                         resultString.Set( GetTextValue( aPointer ) );
       
   577                         break;
       
   578 
       
   579                     case EDateValue:
       
   580                         GetDateValue( aPointer );
       
   581                         break;
       
   582 
       
   583                     default:
       
   584                         break;
       
   585                     }
       
   586 
       
   587                 // We have a result. We're actually only interested in
       
   588                 // SEC and MAC parameters, so we save them here.
       
   589                 switch( paramToken )
       
   590                     {
       
   591                     case KWSPHeaderSEC:
       
   592                         iSEC = resultInteger;
       
   593                         break;
       
   594 
       
   595                     case KWSPHeaderMAC:
       
   596                         iMAC.Set( resultString );
       
   597                         break;
       
   598 
       
   599                     default:
       
   600                         break;
       
   601                     }
       
   602                 }
       
   603             }
       
   604         else
       
   605             {
       
   606             // Unknown parameter. Its name is in text, and the value
       
   607             // might be an integer or text.
       
   608             GetTokenText( aPointer );
       
   609             if( IsIntegerValue( aPointer ) )
       
   610                 {
       
   611                 GetIntegerValue( aPointer );
       
   612                 }
       
   613             else
       
   614                 {
       
   615                 GetTextValue( aPointer );
       
   616                 }
       
   617             }
       
   618         }
       
   619     }
       
   620 
       
   621 
       
   622 // -----------------------------------------------------------------------------
       
   623 // CWPPushMessage::GetQValue
       
   624 // -----------------------------------------------------------------------------
       
   625 //
       
   626 TUint CWPPushMessage::GetQValue( TLex8& aPointer ) const
       
   627     {
       
   628     // q-value is an integer. It is coded as 7 bits per byte.
       
   629     // The highest bit determines if the number continues.
       
   630     TUint result( 0 );
       
   631     TBool lastDigit( EFalse );
       
   632 
       
   633     while( !aPointer.Eos() && !lastDigit )
       
   634         {
       
   635         TInt one( aPointer.Get() );
       
   636 
       
   637         result = (result << 7) || (one & ~KQValueContinuation);
       
   638 
       
   639         if( (one & KQValueContinuation) == 0 )
       
   640             {
       
   641             lastDigit = ETrue;
       
   642             }
       
   643         }
       
   644 
       
   645     return result;
       
   646     }
       
   647 
       
   648 
       
   649 // -----------------------------------------------------------------------------
       
   650 // CWPPushMessage::GetDateValue
       
   651 // -----------------------------------------------------------------------------
       
   652 //
       
   653 TTime CWPPushMessage::GetDateValue( TLex8& aPointer ) const
       
   654     {
       
   655     // Date-value is a long integer and represents seconds
       
   656     // since KDateValueStart.
       
   657     TInt64 result( GetLongInteger( aPointer ) );
       
   658 
       
   659     TTime start( KDateValueStart );
       
   660     TTimeIntervalSeconds delta;
       
   661 
       
   662     delta = I64LOW(result);
       
   663 
       
   664     start += delta;
       
   665     
       
   666     return start;
       
   667     }
       
   668 
       
   669 
       
   670 // -----------------------------------------------------------------------------
       
   671 // CWPPushMessage::GetNoValue
       
   672 // -----------------------------------------------------------------------------
       
   673 //
       
   674 void CWPPushMessage::GetNoValue( TLex8& aPointer ) const
       
   675     {
       
   676     // We're not checking anything here. No value is no value.
       
   677     aPointer.Get();
       
   678     }
       
   679 
       
   680 
       
   681 // -----------------------------------------------------------------------------
       
   682 // CWPPushMessage::GetDeltaSecondsValue
       
   683 // -----------------------------------------------------------------------------
       
   684 //
       
   685 TInt64 CWPPushMessage::GetDeltaSecondsValue( TLex8& aPointer ) const
       
   686     {
       
   687     return GetIntegerValue( aPointer );
       
   688     }
       
   689 
       
   690 
       
   691 // -----------------------------------------------------------------------------
       
   692 // CWPPushMessage::GetConstrainedEncoding
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 TUint CWPPushMessage::GetConstrainedEncoding( TLex8& aPointer ) const
       
   696     {
       
   697     // Constrained encoding can be extension media or short integer
       
   698     TUint result( 0 );
       
   699 
       
   700     if( !aPointer.Eos() )
       
   701         {
       
   702         TUint first( aPointer.Peek() );
       
   703 
       
   704         if( first > KShortIntegerMask )
       
   705             {
       
   706             result = GetShortInteger( aPointer );
       
   707             }
       
   708         else
       
   709             {
       
   710             // Just skip the text version
       
   711             GetTokenText( aPointer );
       
   712             }
       
   713         }
       
   714 
       
   715     return result;
       
   716     }
       
   717 
       
   718 
       
   719 // -----------------------------------------------------------------------------
       
   720 // CWPPushMessage::GetFieldName
       
   721 // -----------------------------------------------------------------------------
       
   722 //
       
   723 TUint CWPPushMessage::GetFieldName( TLex8& aPointer ) const
       
   724     {
       
   725     // Field name can be a short integer or text.
       
   726     TUint result( 0 );
       
   727 
       
   728     if( !aPointer.Eos() )
       
   729         {
       
   730         TUint first( aPointer.Peek() );
       
   731 
       
   732         if( first > KShortIntegerMask )
       
   733             {
       
   734             result = GetShortInteger( aPointer );
       
   735             }
       
   736         else
       
   737             {
       
   738             // Only well-known fields are read
       
   739             GetTokenText( aPointer );
       
   740             }
       
   741         }
       
   742 
       
   743     return result;
       
   744     }
       
   745 
       
   746 
       
   747 // -----------------------------------------------------------------------------
       
   748 // CWPPushMessage::GetTokenText
       
   749 // -----------------------------------------------------------------------------
       
   750 //
       
   751 TPtrC8 CWPPushMessage::GetTokenText( TLex8& aPointer ) const
       
   752     {
       
   753     // Token text is just characters with an end-of-string marker.
       
   754     aPointer.Mark();
       
   755 
       
   756     while( !aPointer.Eos() && aPointer.Get() != EKeyNull )
       
   757         {
       
   758         // Do nothing
       
   759         }
       
   760     
       
   761     return aPointer.MarkedToken();
       
   762     }
       
   763 
       
   764 
       
   765 // -----------------------------------------------------------------------------
       
   766 // CWPPushMessage::GetIntegerValue
       
   767 // -----------------------------------------------------------------------------
       
   768 //
       
   769 TInt64 CWPPushMessage::GetIntegerValue( TLex8& aPointer ) const
       
   770     {
       
   771     // Integer value can be a short integer or a long integer.
       
   772     // Short integer is always >KShortIntegerMask.
       
   773     TInt64 result( 0 );
       
   774 
       
   775     if( !aPointer.Eos() )
       
   776         {
       
   777         TUint first( aPointer.Peek() );
       
   778 
       
   779         if( first > KShortIntegerMask )
       
   780             {
       
   781             result = GetShortInteger( aPointer );
       
   782             }
       
   783         else
       
   784             {
       
   785             result = GetLongInteger( aPointer );
       
   786             }
       
   787         }
       
   788 
       
   789     return result;
       
   790     }
       
   791 
       
   792 
       
   793 // -----------------------------------------------------------------------------
       
   794 // CWPPushMessage::IsIntegerValue
       
   795 // -----------------------------------------------------------------------------
       
   796 //
       
   797 TBool CWPPushMessage::IsIntegerValue( TLex8& aPointer ) const
       
   798     {
       
   799     // Integer values either are above KShortIntegerMask or
       
   800     // their first byte is <=KMaxLongIntegerLength.
       
   801     TBool result( EFalse );
       
   802 
       
   803     if( !aPointer.Eos() )
       
   804         {
       
   805         TUint first( aPointer.Peek() );
       
   806 
       
   807         if( first > KShortIntegerMask || first <= KMaxLongIntegerLength )
       
   808             {
       
   809             result = ETrue;
       
   810             }
       
   811         }
       
   812 
       
   813     return result;
       
   814     }
       
   815 
       
   816 
       
   817 // -----------------------------------------------------------------------------
       
   818 // CWPPushMessage::GetLongInteger
       
   819 // -----------------------------------------------------------------------------
       
   820 //
       
   821 TInt64 CWPPushMessage::GetLongInteger( TLex8& aPointer ) const
       
   822     {
       
   823     // Long integer has length as first byte.
       
   824     TInt64 result( 0 );
       
   825 
       
   826     TInt length( aPointer.Get() );
       
   827     
       
   828     for( TInt i( 0 ); i < length; i++ )
       
   829         {
       
   830         result = (result << 8) + TInt( aPointer.Get() );
       
   831         }
       
   832 
       
   833     return result;
       
   834     }
       
   835 
       
   836 
       
   837 // -----------------------------------------------------------------------------
       
   838 // CWPPushMessage::GetTextValue
       
   839 // -----------------------------------------------------------------------------
       
   840 //
       
   841 TPtrC8 CWPPushMessage::GetTextValue( TLex8& aPointer ) const
       
   842     {
       
   843     // Text-value can be quoted, so skip that first.
       
   844     if( aPointer.Peek() == KQuotedStringStart )
       
   845         {
       
   846         aPointer.Inc();
       
   847         }
       
   848     aPointer.Mark();
       
   849 
       
   850     // It is null-terminated
       
   851     while( aPointer.Get() != EKeyNull )
       
   852         {
       
   853         // Do nothing
       
   854         }
       
   855 
       
   856     // We don't want to have NULL in the resulting descriptor, so
       
   857     // back that out.
       
   858     TPtrC8 result( aPointer.MarkedToken() );
       
   859     result.Set( result.Left( Max( 0, result.Length()-1 ) ) );
       
   860     return result;
       
   861     }
       
   862 
       
   863 
       
   864 // -----------------------------------------------------------------------------
       
   865 // CWPPushMessage::GetWellKnownCharset
       
   866 // -----------------------------------------------------------------------------
       
   867 //
       
   868 TInt64 CWPPushMessage::GetWellKnownCharset( TLex8& aPointer ) const
       
   869     {
       
   870     return GetIntegerValue( aPointer );
       
   871     }
       
   872 
       
   873 
       
   874 // -----------------------------------------------------------------------------
       
   875 // CWPPushMessage::GetVersionValue
       
   876 // -----------------------------------------------------------------------------
       
   877 //
       
   878 TUint CWPPushMessage::GetVersionValue( TLex8& aPointer ) const
       
   879     {
       
   880     // Version-value is a short integer or text. Handle that.
       
   881     TUint result( 0 );
       
   882 
       
   883     if( !aPointer.Eos() )
       
   884         {
       
   885         TUint first( aPointer.Peek() );
       
   886         
       
   887         if( first > KShortIntegerMask )
       
   888             {
       
   889             result = GetShortInteger( aPointer );
       
   890             }
       
   891         else
       
   892             {
       
   893             GetTextString( aPointer );
       
   894             }
       
   895         }
       
   896 
       
   897     return result;
       
   898     }
       
   899 
       
   900 
       
   901 // -----------------------------------------------------------------------------
       
   902 // CWPPushMessage::GetShortInteger
       
   903 // -----------------------------------------------------------------------------
       
   904 //
       
   905 TUint CWPPushMessage::GetShortInteger( TLex8& aPointer ) const
       
   906     {
       
   907     return aPointer.Get() & KShortIntegerMask;
       
   908     }
       
   909 
       
   910 
       
   911 // -----------------------------------------------------------------------------
       
   912 // CWPPushMessage::GetTextString
       
   913 // -----------------------------------------------------------------------------
       
   914 //
       
   915 TPtrC8 CWPPushMessage::GetTextString( TLex8& aPointer ) const
       
   916     {
       
   917     // Text-string can be quoted.
       
   918     if( aPointer.Peek() == KQuotedTextStringStart )
       
   919         {
       
   920         aPointer.Inc();
       
   921         }
       
   922     aPointer.Mark();
       
   923 
       
   924     while( aPointer.Get() != EKeyNull )
       
   925         {
       
   926         // Nothing
       
   927         }
       
   928 
       
   929     // We don't want to have NULL in the resulting descriptor, so
       
   930     // back that out.
       
   931     aPointer.UnGet();
       
   932     TPtrC8 result( aPointer.MarkedToken() );
       
   933     aPointer.Inc();
       
   934     return result;
       
   935     }
       
   936 
       
   937 
       
   938 // -----------------------------------------------------------------------------
       
   939 // CWPPushMessage::ContentTypeHeader
       
   940 // -----------------------------------------------------------------------------
       
   941 //
       
   942 TPtrC8 CWPPushMessage::ContentTypeHeader( CHTTPResponse& aResponse ) const
       
   943     {
       
   944     // We use CHTTPResponse to find first the content-type header.
       
   945     TPtrC8 contentType( KNullDesC8 );
       
   946     TPtrC8 result( KNullDesC8 );
       
   947 
       
   948     if( aResponse.FindBinaryDescField( EHttpContentType, contentType )
       
   949         && contentType.Length() > 0 )
       
   950         {
       
   951         result.Set( contentType );
       
   952 
       
   953         if( result[0] == KContentType )
       
   954             {
       
   955             result.Set( result.Mid(1) );
       
   956             }
       
   957         }
       
   958 
       
   959     return result;
       
   960     }
       
   961 
       
   962 
       
   963 // -----------------------------------------------------------------------------
       
   964 // CWPPushMessage::InitiatorURIHeader
       
   965 // -----------------------------------------------------------------------------
       
   966 //
       
   967 TPtrC8 CWPPushMessage::InitiatorURIHeader( CHTTPResponse& aResponse ) const
       
   968     {
       
   969     // We use CHTTPResponse to find first the content-type header.
       
   970     TPtrC8 initiatorURI( KNullDesC8 );
       
   971     TPtrC8 result( KNullDesC8 );
       
   972 
       
   973     if( aResponse.FindBinaryDescField( EHttpXWapInitiatorURI, initiatorURI )
       
   974         && initiatorURI.Length() > 0 )
       
   975         {
       
   976         result.Set( initiatorURI );
       
   977         }
       
   978 
       
   979     return result;
       
   980     }
       
   981 
       
   982 // -----------------------------------------------------------------------------
       
   983 // CWPPushMessage::PushFlagHeader
       
   984 // -----------------------------------------------------------------------------
       
   985 //
       
   986 TPtrC8 CWPPushMessage::PushFlagHeader( CHTTPResponse& aResponse ) const
       
   987     {
       
   988     // We use CHTTPResponse to find first the content-type header.
       
   989     TPtrC8 pushFlag( KNullDesC8 );
       
   990     TPtrC8 result( KNullDesC8 );
       
   991 
       
   992     if( aResponse.FindBinaryDescField( EHttpPushFlag, pushFlag )
       
   993         && pushFlag.Length() > 0 )
       
   994         {
       
   995         result.Set( pushFlag );
       
   996         }
       
   997 
       
   998     return result;
       
   999     }
       
  1000 
       
  1001 // -----------------------------------------------------------------------------
       
  1002 // CWPPushMessage::AuthenticateL
       
  1003 // The method first checks if there is security information in the message
       
  1004 // with aMessage.SEC(). If yes, the authentication code described in OMA
       
  1005 // Provisioning Bootstrap specification is calculated and compared to the
       
  1006 // one in message header. If the codes match, authentication has been 
       
  1007 // performed succesfully.
       
  1008 // -----------------------------------------------------------------------------
       
  1009 //
       
  1010 EXPORT_C TInt CWPPushMessage::AuthenticateL( const TDesC& aIMSI, 
       
  1011                                             const TDesC& aPIN )
       
  1012     {
       
  1013     FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL:" ) );
       
  1014     
       
  1015     TInt result( KWPAuthResultAuthenticated );
       
  1016 
       
  1017     // Retrieve the MAC from message
       
  1018     ParseHeaderL();
       
  1019 
       
  1020     // The HMAC is in ASCII HEX format. Convert to binary.
       
  1021     HBufC8* headerMac = PackLC( MAC() );
       
  1022 
       
  1023     // Create space for key
       
  1024     HBufC8* key = HBufC8::NewLC( Max( 1, aIMSI.Length() + aPIN.Length() ) );
       
  1025     TPtr8 keyPtr( key->Des() );
       
  1026     // Check if only NETWPIN authentication is allowed, from central repository.
       
  1027     TInt value( 0 );
       
  1028 	CRepository* repository = CRepository::NewLC( KOMAProvAuthenticationLV );
       
  1029 	User::LeaveIfError( repository->Get( KOMAProvAuthenticationLVFlag, value ) );
       
  1030 	CleanupStack::PopAndDestroy(); // repository
       
  1031 
       
  1032     // We support only security type NETWPIN
       
  1033     switch( SEC() )
       
  1034         {
       
  1035         case KSECNETWPIN:
       
  1036             {
       
  1037             FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KSECNETWPIN" ) );
       
  1038             // Get the key to be used in HMAC calculation
       
  1039             ConvertIMSIL( aIMSI, keyPtr );
       
  1040             break;
       
  1041             }
       
  1042 
       
  1043         case KSECUSERPIN:
       
  1044             {
       
  1045             FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KSECUSERPIN" ) );
       
  1046             if (EAuthNETWPINOnly != value)
       
  1047             	{
       
  1048             	if( aPIN.Length() == 0 )
       
  1049                 	{
       
  1050                 	result = KWPAuthResultPinRequired;
       
  1051                 	FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultPinRequired" ) );
       
  1052                 	}
       
  1053             	keyPtr.Copy( aPIN );
       
  1054             	}
       
  1055             else
       
  1056                	{
       
  1057                	result = KWPAuthResultAuthenticationFailed;
       
  1058                	FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultAuthenticationFailed" ) );
       
  1059                	}
       
  1060             break;
       
  1061             }
       
  1062 
       
  1063         case KSECUSERNETWPIN:
       
  1064             {
       
  1065             FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KSECUSERNETWPIN" ) );
       
  1066             if (EAuthNETWPINOnly != value)
       
  1067             	{
       
  1068             	if( aPIN.Length() == 0 )
       
  1069                 	{
       
  1070 	                result = KWPAuthResultPinRequired;
       
  1071 	                FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultPinRequired" ) );
       
  1072     	            }
       
  1073 
       
  1074         	    ConvertIMSIL( aIMSI, keyPtr );
       
  1075 	            keyPtr.Append( aPIN );
       
  1076             	}
       
  1077             else
       
  1078             	{
       
  1079 				result = KWPAuthResultAuthenticationFailed;   
       
  1080 				FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultAuthenticationFailed" ) );         		
       
  1081             	}
       
  1082             break;
       
  1083             }
       
  1084 
       
  1085         case KSECUSERPINMAC:
       
  1086             {
       
  1087             FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KSECUSERPINMAC" ) );
       
  1088             if (EAuthNETWPINOnly != value)
       
  1089             	{
       
  1090 	            if( aPIN.Length() == 0 )
       
  1091     	            {
       
  1092         	        result = KWPAuthResultPinRequired;
       
  1093         	        FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultPinRequired" ) );
       
  1094             	    }
       
  1095             	keyPtr.Copy( aPIN );
       
  1096             	}
       
  1097             else
       
  1098            		{
       
  1099 				result = KWPAuthResultAuthenticationFailed;            	    	
       
  1100 				FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultAuthenticationFailed" ) );
       
  1101            	    }
       
  1102             break;
       
  1103             }
       
  1104 
       
  1105         default:
       
  1106             {
       
  1107             FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: default" ) );
       
  1108             if (EAuthNETWPINOnly == value || EAuthNoSecurity == value )
       
  1109             	{
       
  1110             	result = KWPAuthResultAuthenticationFailed;
       
  1111             	FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultAuthenticationFailed" ) );
       
  1112             	}
       
  1113             else
       
  1114             	{
       
  1115             	result = KWPAuthResultNoAuthentication;	
       
  1116             	FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultNoAuthentication" ) );
       
  1117             	}            	
       
  1118             break;
       
  1119             }
       
  1120         }
       
  1121          
       
  1122     if( result == KWPAuthResultAuthenticated )
       
  1123         {
       
  1124         FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: KWPAuthResultAuthenticated" ) );
       
  1125         CMessageDigest* digest = CSHA1::NewL();
       
  1126         CleanupStack::PushL( digest );
       
  1127 
       
  1128         if( SEC() == KSECUSERPINMAC )
       
  1129             {
       
  1130             // key C is a concatenation of pin K and digest m
       
  1131             TPtrC8 K( key->Left( key->Length()/2 ) );
       
  1132             TPtrC8 m( key->Right( key->Length()/2 ) );
       
  1133 
       
  1134             // M' = HMAC-SHA(K, A)
       
  1135             CHMAC* hmac = CHMAC::NewL( K, digest );
       
  1136             CleanupStack::Pop( digest );
       
  1137             CleanupStack::PushL( hmac );
       
  1138             TPtrC8 MM( hmac->Hash( Body() ) );
       
  1139     
       
  1140             // Create m' (renamed to mm)
       
  1141             HBufC8* mm = HBufC8::NewLC( m.Length() );
       
  1142             TPtr8 ptr( mm->Des() );
       
  1143             for( TInt i( 0 ); i < m.Length(); i++ )
       
  1144                 {
       
  1145                 ptr.Append( (MM[i]%10)+KZero );
       
  1146                 }
       
  1147 
       
  1148             // Compare the MACs and mark the message as authenticated
       
  1149             if( *mm != m )
       
  1150                 {
       
  1151                 result = KWPAuthResultAuthenticationFailed;
       
  1152                 }
       
  1153             CleanupStack::PopAndDestroy(); // mm
       
  1154             }
       
  1155         else
       
  1156             {
       
  1157             FLOG( _L( "[Provisioning] CWPPushMessage::AuthenticateL: not KWPAuthResultAuthenticated" ) );
       
  1158             // Create the HMAC from body
       
  1159             CHMAC* hmac = CHMAC::NewL( *key, digest );
       
  1160             CleanupStack::Pop( digest );
       
  1161             CleanupStack::PushL( hmac );
       
  1162     
       
  1163             // Compare the MACs and mark the message as authenticated
       
  1164             if( headerMac->Length() == 0 
       
  1165                 || hmac->Hash( Body() ) != *headerMac )
       
  1166                 {
       
  1167                 result = KWPAuthResultAuthenticationFailed;
       
  1168                 }
       
  1169             }
       
  1170         CleanupStack::PopAndDestroy(); // hmac
       
  1171         }
       
  1172             
       
  1173     CleanupStack::PopAndDestroy( 2 ); // key, headerMac
       
  1174 
       
  1175     return result;
       
  1176     }
       
  1177 
       
  1178 // -----------------------------------------------------------------------------
       
  1179 // CWPPushMessage::PackL
       
  1180 // -----------------------------------------------------------------------------
       
  1181 //
       
  1182 HBufC8* CWPPushMessage::PackLC( const TDesC8& aHex ) const
       
  1183     {
       
  1184     HBufC8* bin = HBufC8::NewLC( aHex.Length()/2 );
       
  1185     TPtr8 binPtr( bin->Des() );
       
  1186     for( TInt i( 0 ); i < aHex.Length()/2; i++ )
       
  1187         {
       
  1188         TLex8 lex( aHex.Mid( i*2, 2 ) );
       
  1189         TUint8 byte( 0 );
       
  1190         User::LeaveIfError( lex.Val( byte, EHex ) );
       
  1191         binPtr.Append( TUint8( byte ) );
       
  1192         }
       
  1193 
       
  1194     return bin;
       
  1195     }
       
  1196 
       
  1197 // -----------------------------------------------------------------------------
       
  1198 // CWPPushMessage::ConvertIMSIL
       
  1199 // -----------------------------------------------------------------------------
       
  1200 //
       
  1201 void CWPPushMessage::ConvertIMSIL( const TDesC& aIMSI, TPtr8& aKey ) const
       
  1202     {
       
  1203     TUint8 parity( TUint8((aIMSI.Length() % 2) << KParityBitNum) );
       
  1204 
       
  1205     if( aIMSI.Length() == 0 )
       
  1206         {
       
  1207         aKey.Append( (KPadNibble<<KNumBitsInNibble) + KFirstNibble + parity );
       
  1208         return;
       
  1209         }
       
  1210 
       
  1211     // First byte contains just a header and one digit
       
  1212     TInt first( aIMSI[0] - KZero );
       
  1213     aKey.Append( (first<<KNumBitsInNibble) | KFirstNibble | parity );
       
  1214 
       
  1215     // Use semi-octet or BCD packing of IMSI. It means that one byte contains
       
  1216     // two decimal numbers, each in its own nibble.
       
  1217     for( TInt i( 1 ); i < aIMSI.Length(); i += KNumDigitsInByte )
       
  1218         {
       
  1219         first = aIMSI[i] - KZero;
       
  1220         TInt second( 0 );
       
  1221 
       
  1222         if( aIMSI.Length() == i+1 )
       
  1223             {
       
  1224             second = KPadNibble;
       
  1225             }
       
  1226         else
       
  1227             {
       
  1228             second = aIMSI[i+1] - KZero;
       
  1229             }
       
  1230 
       
  1231         aKey.Append( (second<<KNumBitsInNibble) + first );
       
  1232         }
       
  1233     }
       
  1234 
       
  1235 
       
  1236 
       
  1237 //  End of File