diff -r 000000000000 -r 3ce708148e4d pnpmobileservices/pnpms/PnP/NHwrParser/HttpProvContent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pnpmobileservices/pnpms/PnP/NHwrParser/HttpProvContent.cpp Thu Dec 17 08:40:12 2009 +0200 @@ -0,0 +1,361 @@ +/* +* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of PnPMS components +* +*/ + + + +// INCLUDE FILES +#include + +#include "HttpProvContent.h" +#include "HttpProvContentType.h" +#include "NHwrParserLogger.h" +#include "HttpProvHeaders.h" +#include "PnpUtilImpl.h" + +// CONSTANTS + +// Number of BCD digits in byte +const TInt KNumDigitsInByte = 2; + +// Number of bits in half-byte +const TInt KNumBitsInNibble = 4; + +// Ascii code for zero +const TUint8 KZero = '0'; + +// Padding half-byte +const TUint8 KPadNibble = 0xf; + +// First nibble +const TUint8 KFirstNibble = 0x1; + +// Parity bit number in first nibble +const TUint KParityBitNum = 3; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CHttpProvContent::CHttpProvContent +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CHttpProvContent::CHttpProvContent() : iAuthenticated( EFalse) + { + } + +// ----------------------------------------------------------------------------- +// CHttpProvContent::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CHttpProvContent::ConstructL( const TPtrC8 aContent ) + { + iContent.Set( aContent ); + } + +// ----------------------------------------------------------------------------- +// CHttpProvContent::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CHttpProvContent* CHttpProvContent::NewL(const TPtrC8 aContent) + { + LOGSTRING( "CHttpProvContent::NewL()" ); + CHttpProvContent* self = NewLC(aContent); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CHttpProvContent::NewLC +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CHttpProvContent* CHttpProvContent::NewLC(const TPtrC8 aContent) + { + LOGSTRING( "CHttpProvContent::NewLC()" ); + CHttpProvContent* self = new(ELeave) CHttpProvContent; + CleanupStack::PushL(self); + self->ConstructL(aContent); + return self; + } + +// Destructor +CHttpProvContent::~CHttpProvContent() + { + LOGSTRING( "~CHttpProvContent - done" ); + } + +// ----------------------------------------------------------------------------- +// CHttpProvContent::AuthenticateL +// ----------------------------------------------------------------------------- +// +TInt CHttpProvContent::AuthenticateL( const CHttpProvHeaders& aHeaders, CHttpProvContentType& aContentType ) + { + LOGSTRING( "CHttpProvContent::AuthenticateL" ); + + TInt result( KHttpProvAuthResultAuthenticated ); + + CPnpUtilImpl* pnpUtil = CPnpUtilImpl::NewLC(); + + TInt token = 0; + TBuf8<4> tokenbuf; // Token cannot be more the 4 characters long + tokenbuf.Zero(); + + RMobilePhone::TMobilePhoneSubscriberId imsi; + // util->Imsi(imsi); + // RDebug::Print(imsi); + + // Create space for key + HBufC8* key = HBufC8::NewLC( Max( 1, imsi.MaxLength() + tokenbuf.MaxLength() ) ); + TPtr8 keyPtr( key->Des() ); + + LOGSTRING2( "Content type SEC: %i", aContentType.SEC() ); + + // We support only security type NETWPIN + switch( aContentType.SEC() ) + { + case KSECUSERPIN: + { + LOGSTRING("KSECUSERPIN"); + // Get token saved by ConfManager + TInt err = pnpUtil->GetTokenValue( token ); + tokenbuf.AppendNum(token); + if( err != KErrNone ) + { + result = KHttpProvAuthResultTokenExpired; + } + else if( tokenbuf.Length() == 0 ) + { + result = KHttpProvAuthResultPinRequired; + } + + keyPtr.Copy( tokenbuf ); + if( result == KHttpProvAuthResultAuthenticated ) + AuthenticateSenderL( *key, aContentType, result ); + break; + } + + case KSECUSERNETWPIN: + { + LOGSTRING("KSECUSERNETWPIN"); + // Get token saved by ConfManager + TInt err = pnpUtil->GetTokenValue( token ); + tokenbuf.AppendNum(token); + if( err != KErrNone ) + { + result = KHttpProvAuthResultTokenExpired; + } + else if( tokenbuf.Length() == 0 ) + { + result = KHttpProvAuthResultPinRequired; + } + + ConvertIMSIL( imsi, keyPtr ); + keyPtr.Append( tokenbuf ); + + if( result == KHttpProvAuthResultAuthenticated ) + AuthenticateSenderL( *key, aContentType, result ); + break; + } + + case KSECUSERPINMAC: + { + LOGSTRING("KSECUSERPINMAC"); + // Get token saved by ConfManager + TInt err = pnpUtil->GetTokenValue( token ); + tokenbuf.AppendNum(token); + if( err != KErrNone ) + { + result = KHttpProvAuthResultTokenExpired; + } + else if( tokenbuf.Length() == 0 ) + { + result = KHttpProvAuthResultPinRequired; + } + + keyPtr.Copy( tokenbuf ); + + if( result == KHttpProvAuthResultAuthenticated ) + AuthenticateSenderL( *key, aContentType, result ); + break; + } + case KSECPKA: + { + LOGSTRING("KSECPKA"); + LOGSTRING( "Get nonce" ); + TBuf8 nonce; + pnpUtil->GetNonceL( nonce ); + + LOGSTRING( "Verify signature" ); + // Verify digest (Hash value of "nonce:data") and signature of the sender + if( !pnpUtil->VerifySignatureL( + aHeaders.GetParamValL( KDigestValue ), + aHeaders.GetParamValL( KSignatureValue ), + iContent, + nonce ) ) + { + LOGSTRING("Signature verify failed"); + result = KHttpProvAuthResultAuthenticationFailed; + } + else + { + LOGSTRING("Signature verified"); + } + break; + } + default: + { + LOGSTRING("No authentication"); + result = KHttpProvAuthResultNoAuthentication; + } + } + + + CleanupStack::PopAndDestroy( key ); // key, headerMac + + CleanupStack::PopAndDestroy( pnpUtil ); + + LOGSTRING2( "CHttpProvContent::AuthenticateL - done: %i", result ); + + return result; + } + +void CHttpProvContent::AuthenticateSenderL( const TDesC8& aKey, CHttpProvContentType& aContentType, TInt& aResult ) + { + LOGSTRING( "CHttpProvContent::AuthenticateSenderL" ); + // The HMAC is in ASCII HEX format. Convert to binary. + TPtrC8 mac; + aContentType.MACL(mac); + LOGSTRING( "mac:" ); + LOGTEXT( mac ); + HBufC8* headerMac = PackLC( mac ); + CMessageDigest* digest = CSHA1::NewL(); + CleanupStack::PushL( digest ); + + if( aContentType.SEC() == KSECUSERPINMAC ) + { + // key C is a concatenation of pin K and digest m + TPtrC8 K( aKey.Left( aKey.Length()/2 ) ); + TPtrC8 m( aKey.Right( aKey.Length()/2 ) ); + + // M' = HMAC-SHA(K, A) + CHMAC* hmac = CHMAC::NewL( K, digest ); + // Ownership of digest is transferred to hmac created above + CleanupStack::Pop( digest ); + CleanupStack::PushL( hmac ); + TPtrC8 MM( hmac->Hash( iContent ) ); + + // Create m' (renamed to mm) + HBufC8* mm = HBufC8::NewLC( m.Length() ); + TPtr8 ptr( mm->Des() ); + for( TInt i( 0 ); i < m.Length(); i++ ) + { + ptr.Append( (MM[i]%10)+KZero ); + } + + // Compare the MACs and mark the message as authenticated + if( *mm != m ) + { + aResult = KHttpProvAuthResultAuthenticationFailed; + } + CleanupStack::PopAndDestroy( mm ); + CleanupStack::PopAndDestroy( hmac ); + } + else + { + // Create the HMAC from body + CHMAC* hmac = CHMAC::NewL( aKey, digest ); + LOGTEXT( aKey ); + // Ownership of digest is transferred to hmac created above + CleanupStack::Pop( digest ); + CleanupStack::PushL( hmac ); + + // Compare the MACs and mark the message as authenticated + TPtrC8 temp = hmac->Hash( iContent ); + if( headerMac->Length() == 0 + || temp != *headerMac ) + { + LOGSTRING( "KHttpProvAuthResultAuthenticationFailed" ); + aResult = KHttpProvAuthResultAuthenticationFailed; + } + CleanupStack::PopAndDestroy( hmac ); + } + CleanupStack::PopAndDestroy( headerMac ); + } + +// ----------------------------------------------------------------------------- +// CHttpProvContent::PackLC +// ----------------------------------------------------------------------------- +// +HBufC8* CHttpProvContent::PackLC( const TDesC8& aHex ) const + { + HBufC8* bin = HBufC8::NewLC( aHex.Length()/2 ); + TPtr8 binPtr( bin->Des() ); + for( TInt i( 0 ); i < aHex.Length()/2; i++ ) + { + TLex8 lex( aHex.Mid( i*2, 2 ) ); + TUint8 byte( 0 ); + User::LeaveIfError( lex.Val( byte, EHex ) ); + binPtr.Append( TUint8( byte ) ); + } + + return bin; + } + +// ----------------------------------------------------------------------------- +// CHttpProvContent::ConvertIMSIL +// ----------------------------------------------------------------------------- +// +void CHttpProvContent::ConvertIMSIL( const TDesC& aIMSI, TPtr8& aKey ) const + { + TUint8 parity( TUint8((aIMSI.Length() % 2) << KParityBitNum) ); + + if( aIMSI.Length() == 0 ) + { + aKey.Append( (KPadNibble<