realtimenetprots/sipfw/SIP/SIPSec/DigestPlugin/src/CSIPSecSIMCredentialsProvider.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/SIPSec/DigestPlugin/src/CSIPSecSIMCredentialsProvider.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,691 @@
+// Copyright (c) 2007-2009 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:
+// Name          : CSIPSecSIMCredentialsProvider.cpp
+// Part of       : SIPSec
+// Version       : SIP/6.0
+//
+
+
+
+#include <commsdat.h>
+#include <commsdattypesv1_1.h>
+#include <mmretrieve.h>
+#include <etelmmerr.h>
+#include <cdblen.h>
+
+#include "SipLogs.h"
+#include "SipAssert.h"
+#include "CSIPSecSIMCredentialsProvider.h"
+#include "CSIPSecSIMRecord.h"
+#include "CSIPSecDigestPlugin.h"
+#include "sipsecdigestcontext.h"
+
+// CONSTANTS
+_LIT8( KSIPSecCK, "ck" );
+_LIT8( KSIPSecIK, "ik" );
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::NewL
+// ----------------------------------------------------------------------------
+//
+CSIPSecIMSAuthentication* CSIPSecIMSAuthentication::NewL(
+         MSIPSecIMSAuthenticationDataObserver& aObserver )
+    {
+    return new ( ELeave ) CSIPSecIMSAuthentication( aObserver );    
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::CSIPSecIMSAuthentication
+// ----------------------------------------------------------------------------
+//
+CSIPSecIMSAuthentication::CSIPSecIMSAuthentication( 
+            MSIPSecIMSAuthenticationDataObserver& aObserver ) :
+    CActive( CActive::EPriorityStandard ),
+    iObserver( aObserver ),
+    iPhone( NULL ),    
+    iMessage( iData )
+    {
+    CActiveScheduler::Add( this );
+    }
+        
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::~CSIPSecIMSAuthentication
+// ----------------------------------------------------------------------------
+//
+CSIPSecIMSAuthentication::~CSIPSecIMSAuthentication()
+    {
+    Cancel();
+    }
+
+#ifndef USE_TEST_STUB
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::Request
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthentication::Request( RMobilePhone& aPhone )
+    {
+    __SIP_LOG( "CSIPSecIMSAuthen:Request" )
+	__ASSERT_ALWAYS( !IsActive(),
+					 User::Panic( _L( "IMSAuthentic:Req" ), KErrInUse ) );
+
+	iMessage.Copy( RMobilePhone::TImsAuthenticateDataV5Pckg( iData ) );
+
+    __SIP_LOG( "CSIPSecIMSAuthen:Request Asking ISIM to Authenticate" )
+	aPhone.ImsAuthenticate( iStatus, iMessage );
+    SetActive();
+    iPhone = &aPhone;	
+    }
+#endif // #ifndef USE_TEST_STUB
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::Response
+// ----------------------------------------------------------------------------
+//
+RMobilePhone::TImsAuthenticateDataV5& CSIPSecIMSAuthentication::Response()
+    {
+    return iData;
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::RunL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthentication::RunL()
+    {
+	__SIP_INT_LOG1( "SIPSecIMSAuthen:RunL status", iStatus.Int() )    
+
+    if ( iStatus.Int() == KErrNone )
+        {
+        iObserver.AuthenticatedL();
+        }
+    else
+        {
+        iObserver.AuthenticationFailedL( iStatus.Int() );        
+        }
+   	iPhone = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::RunError
+// -----------------------------------------------------------------------------
+//
+TInt CSIPSecIMSAuthentication::RunError( TInt aError )
+    {
+	return iObserver.PassErrorToFramework( aError, ETrue );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthentication::DoCancel
+// As there is a pending request, iPhone must be defined.
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthentication::DoCancel()
+    {
+#if defined( USE_TEST_STUB )
+    // If CSIPSecDigestTest::AKAAuthWWWChallengeFailuresTestL leaves before it
+    // called iSIMStub->CallBack, this is needed to cancel the active object.
+	TRequestStatus* status = &iStatus;
+   	User::RequestComplete( status, KErrCancel );
+#else
+ 	__SIP_LOG( "CSIPSecIMSAuthen:DoCancel" )
+
+    __SIP_ASSERT_RETURN( iPhone, KErrNotFound );    
+
+	iPhone->CancelAsyncRequest( EMobilePhoneIMSAuthenticate );	
+#endif
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::NewL
+// ----------------------------------------------------------------------------
+//
+CSIPSecIMSAuthorization*
+CSIPSecIMSAuthorization::NewL( MSIPSecIMSAuthenticationDataObserver& aObserver )
+    {
+    CSIPSecIMSAuthorization* self = 
+        new ( ELeave ) CSIPSecIMSAuthorization( aObserver );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;    
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::CSIPSecIMSAuthorization
+// ----------------------------------------------------------------------------
+//
+CSIPSecIMSAuthorization::CSIPSecIMSAuthorization( 
+        MSIPSecIMSAuthenticationDataObserver& aObserver ) :
+    CActive( CActive::EPriorityStandard ),
+    iObserver( aObserver )
+    {
+    }
+        
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::~CSIPSecIMSAuthorization
+// ----------------------------------------------------------------------------
+//
+CSIPSecIMSAuthorization::~CSIPSecIMSAuthorization()
+    {
+    Cancel();
+    delete iRetriever;
+    delete iData;
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::ConstructL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthorization::ConstructL()
+    {    
+    iData = RMobilePhone::CImsAuthorizationInfoV5::NewL();
+    CActiveScheduler::Add( this );    
+    }
+
+#ifndef USE_TEST_STUB
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::RequestL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthorization::RequestL( RMobilePhone& aPhone )
+    {
+    delete iRetriever;
+    iRetriever = NULL;
+    iRetriever = CAsyncRetrieveAuthorizationInfo::NewL( aPhone, *iData );
+
+    iRetriever->Start( iStatus );
+    SetActive();
+    }
+#endif // #ifndef USE_TEST_STUB
+
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::Response
+// ----------------------------------------------------------------------------
+//
+RMobilePhone::CImsAuthorizationInfoV5& CSIPSecIMSAuthorization::Response()
+    {
+    return *iData;
+    }   
+
+#ifndef USE_TEST_STUB
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::RunL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthorization::RunL()
+    {
+	if ( iStatus.Int() == KErrNone &&
+		 iRetriever &&
+		 iRetriever->AuthInfoValid() )
+        {
+        iObserver.Authorized();
+        }
+    else
+        {
+        iObserver.AuthorizationFailedL();
+        }
+    }
+#endif // #ifndef USE_TEST_STUB
+
+// -----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::RunError
+// -----------------------------------------------------------------------------
+//
+TInt CSIPSecIMSAuthorization::RunError( TInt aError )	
+    {
+	return iObserver.PassErrorToFramework( aError, EFalse );	
+	}
+        
+// ----------------------------------------------------------------------------
+// CSIPSecIMSAuthorization::DoCancel
+// ----------------------------------------------------------------------------
+//
+void CSIPSecIMSAuthorization::DoCancel()
+    {
+#if defined( USE_TEST_STUB )
+    // If using test stub, must cancel own request as iRetriever is always NULL
+	TRequestStatus* status = &iStatus;
+   	User::RequestComplete( status, KErrCancel );
+#endif
+    __SIP_LOG( "CSIPSecIMSAuthor:DoCancel" )
+
+	if ( iRetriever )
+		{
+		iRetriever->Cancel();
+		}
+    delete iRetriever;
+    iRetriever = NULL;
+    }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::NewL
+// ----------------------------------------------------------------------------
+//
+CSIPSecSIMCredentialsProvider*
+CSIPSecSIMCredentialsProvider::NewL( CSIPSecSIMRecord& aRecord )
+    {
+    CSIPSecSIMCredentialsProvider* self =
+		new ( ELeave ) CSIPSecSIMCredentialsProvider( aRecord );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::CSIPSecSIMCredentialsProvider
+// ----------------------------------------------------------------------------
+//
+CSIPSecSIMCredentialsProvider::CSIPSecSIMCredentialsProvider(
+	CSIPSecSIMRecord& aRecord ) :
+	CSIPSecCredentialsProvider( aRecord )
+	{
+	}
+
+#ifndef USE_TEST_STUB
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::ConstructL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::ConstructL()
+    {
+	TBuf<KCommsDbSvrMaxFieldLength> tsyModuleName;
+	GetTsyModuleNameL( tsyModuleName );
+	PreparePhoneL( tsyModuleName );
+
+    iAuthentication = CSIPSecIMSAuthentication::NewL( *this );
+    iAuthorization = CSIPSecIMSAuthorization::NewL( *this );
+    }
+#endif // #ifndef USE_TEST_STUB
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::~CSIPSecSIMCredentialsProvider
+// ----------------------------------------------------------------------------
+//
+CSIPSecSIMCredentialsProvider::~CSIPSecSIMCredentialsProvider()
+    {
+    __SIP_LOG( "~SIPSecSIMCredProv" )
+
+    delete iAuthentication;
+    delete iAuthorization;
+    delete iOutboundProxy;
+
+    iPhone.Close();
+    iEtelServer.Close();
+
+	__SIP_LOG( "~SIPSecSIMCredProv ends" )
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::GetTsyModuleNameL
+// ----------------------------------------------------------------------------
+//
+void
+CSIPSecSIMCredentialsProvider::GetTsyModuleNameL( TDes& aTsyModuleName ) const
+    {
+    __ASSERT_ALWAYS( aTsyModuleName.MaxSize() >= KCommsDbSvrMaxFieldLength,
+		User::Leave( KErrArgument ) );
+
+    using namespace CommsDat;
+
+    CMDBSession* db = CMDBSession::NewLC( KCDVersion1_1 ); 
+
+    CMDBField<TUint32>* globalSettingField =
+    	new ( ELeave ) CMDBField<TUint32>( KCDTIdModemPhoneServicesSMS );
+    CleanupStack::PushL( globalSettingField );
+
+    globalSettingField->SetRecordId( 1 );
+    globalSettingField->LoadL( *db );
+    TUint32 modemId = *globalSettingField; 
+
+    CMDBField<TDesC>* tsyField =
+    	new ( ELeave ) CMDBField<TDesC>( KCDTIdTsyName );
+    CleanupStack::PushL( tsyField );
+
+    tsyField->SetRecordId( modemId ); 
+    tsyField->LoadL( *db );
+    aTsyModuleName = *tsyField;
+
+    CleanupStack::PopAndDestroy( tsyField );
+    CleanupStack::PopAndDestroy( globalSettingField );
+    CleanupStack::PopAndDestroy( db );
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::PreparePhoneL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::PreparePhoneL( const TDes& aTsyModuleName )
+	{
+    User::LeaveIfError( iEtelServer.Connect() );
+    User::LeaveIfError( iEtelServer.LoadPhoneModule( aTsyModuleName ) );
+
+    // Get number of phones supported by all currently loaded TSY modules
+    TInt phoneCount( 0 );
+    User::LeaveIfError( iEtelServer.EnumeratePhones( phoneCount ) );
+
+    RTelServer::TPhoneInfo phoneInfo;
+	TName searchTsyName;
+	TInt phoneIndex( KErrNotFound );
+
+    while ( phoneIndex == KErrNotFound && phoneCount-- > 0 )
+        {
+        // Check if this phone belongs to the loaded TSY
+        if ( ( iEtelServer.GetTsyName( phoneCount, searchTsyName ) == KErrNone )
+             &&
+             ( searchTsyName.CompareF( aTsyModuleName ) == 0 ) )
+        	{
+        	phoneIndex = phoneCount;        	
+        	}
+        }
+	if ( phoneIndex == KErrNotFound )
+		{
+		User::Leave( KErrNotFound );
+		}
+
+    User::LeaveIfError( iEtelServer.GetPhoneInfo( phoneIndex, phoneInfo ) );
+    User::LeaveIfError( iPhone.Open( iEtelServer, phoneInfo.iName ) );	
+
+    RPhone::TStatus phoneStatus;
+    User::LeaveIfError( iPhone.GetStatus( phoneStatus ) );
+
+    // Check if the phone is already initialised
+    if ( phoneStatus.iMode == RPhone::EModeUnknown )
+        {
+        TInt err = iPhone.Initialise();
+
+        if ( err != KErrNone )
+            {
+            iPhone.Close();
+            User::Leave( err );
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::RequestL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::RequestL( TSIPSecDigestCtxSetup& aContext )
+    {
+    iPlugin = &aContext.Parent().Plugin();
+
+    delete iOutboundProxy;
+    iOutboundProxy = NULL;
+    iOutboundProxy = aContext.Parent().OutboundProxy().AllocL();
+
+    static_cast<CSIPSecSIMRecord&>( UserRecord() ).SetAuthenticationDataL(
+    	aContext.Nonce() );
+
+    if ( UserRecord().UserName().Length() == 0 )
+        {
+        RequestUserNameL();
+        }
+    else
+        {
+        RequestPassword();
+        }
+    }
+    
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::RequestUserNameL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::RequestUserNameL()
+    {
+    RMobilePhone::CImsAuthorizationInfoV5& data = iAuthorization->Response();
+
+    data.iIMPI.Zero();
+    data.iIMPUArray.Reset();
+    data.iHomeNetworkDomainName.Zero();
+
+    iAuthorization->RequestL( iPhone );
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::RequestPassword
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::RequestPassword()
+    {
+    CSIPSecSIMRecord& record = static_cast<CSIPSecSIMRecord&>( UserRecord() );
+
+    RMobilePhone::TImsAuthenticateDataV5& data = iAuthentication->Response();
+    data.iRAND.Zero();
+    data.iAUTN.Zero();
+    data.iRES.Zero();
+	data.iIK.Zero();
+    data.iCK.Zero();
+    data.iAUTS.Zero();
+
+    data.iRAND.Copy( record.RAND() );
+	data.iAUTN.Copy( record.AUTN() );
+
+	__SIP_INT_LOG2( "SIPSecSIMCredProv:RequestPassword, RAND len, AUTN len",
+	                record.RAND().Length(), record.AUTN().Length() )
+	HexDumpToLog( _L8( "RAND=" ), record.RAND() );	
+	HexDumpToLog( _L8( "AUTN=" ), record.AUTN() );
+
+    iAuthentication->Request( iPhone );
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::Cancel
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::Cancel()
+    {
+    iAuthentication->Cancel();
+    iAuthorization->Cancel();
+    }
+    
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::AuthenticatedL
+// For AKA, use the challenge's realm, not the SIM's realm. AUTS does not exist.
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::AuthenticatedL()
+    {
+    __SIP_LOG( "SIPSecSIMCredProv:AuthenticatedL" )
+    __SIP_ASSERT_LEAVE( iPlugin && iOutboundProxy, KErrNotFound );
+
+    RMobilePhone::CImsAuthorizationInfoV5& authorization =
+    	iAuthorization->Response();
+    RMobilePhone::TImsAuthenticateDataV5& authentication =
+		iAuthentication->Response();
+
+	__SIP_INT_LOG2( "Lengths: IK, CK",
+	                authentication.iIK.Length(),
+			        authentication.iCK.Length() )
+	__SIP_INT_LOG2( "Lengths: IMPI, RES",       
+			        authorization.iIMPI.Length(),
+			        authentication.iRES.Length() )
+	__SIP_INT_LOG1( "Lengths: AUTS", authentication.iAUTS.Length() )
+
+	HexDumpToLog( _L8( "IK=" ), authentication.iIK );
+	HexDumpToLog( _L8( "CK=" ), authentication.iCK );
+	HexDumpToLog( _L8( "RES=" ), authentication.iRES );
+
+    iPlugin->EngineContext().RemoveValue( KSIPSecIK );
+    iPlugin->EngineContext().RemoveValue( KSIPSecCK );
+   	iPlugin->EngineContext().SetValueL( KSIPSecIK, authentication.iIK );
+   	iPlugin->EngineContext().SetValueL( KSIPSecCK, authentication.iCK );
+    iPlugin->SetCredentialsL( UserRecord().SIPSecUser(),
+                              UserRecord().Realm(),
+                              *iOutboundProxy,
+                              authorization.iIMPI,   // username
+                              authentication.iRES ); // password
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::AuthenticationFailedL
+// If SQN failure, AUTS is set. Compute credentials using an empty password.
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::AuthenticationFailedL( TInt aError )
+    {
+	__SIP_LOG( "SIPSecSIMCredProv:AuthenticFailedL" )
+	__SIP_ASSERT_RETURN( aError != KErrNone, KErrArgument );
+    __SIP_ASSERT_RETURN( iPlugin && iOutboundProxy, KErrNotFound );    
+
+	const TDesC8& res = iAuthentication->Response().iRES;	
+	const TDesC8& auts = iAuthentication->Response().iAUTS;
+
+	__SIP_INT_LOG2( "Lengths RES, AUTS", res.Length(), auts.Length() )
+	HexDumpToLog( _L8( "AUTS=" ), auts );
+
+	__ASSERT_ALWAYS( res.Length() == 0, User::Leave( KErrGeneral ) );
+
+	CSIPSecSIMRecord& record = static_cast<CSIPSecSIMRecord&>( UserRecord() );
+	switch ( aError )
+		{
+		case KErrMMEtelMacVerificationFailed:
+			record.UserCredentialsFailed( CSIPSecSIMRecord::EMAC );
+			break;
+
+		case KErrMMEtelSqnVerificationFailed:			
+			__ASSERT_ALWAYS( auts.Length() > 0, User::Leave( KErrGeneral ) );
+
+			record.UserCredentialsFailed( CSIPSecSIMRecord::ESQN );
+        	record.SetResynchronizationDataL( auts );
+			break;
+
+		case KErrMMEtelAuthenticateFailed: // Authenticate command failed		
+		default: // System wide errors
+			User::Leave( aError );
+		}
+
+	iPlugin->EngineContext().RemoveValue( KSIPSecIK );
+    iPlugin->EngineContext().RemoveValue( KSIPSecCK );
+
+	// Though using record.TransactionId() works too, it is better to use
+	// userRecord().SIPSecUser() as transaction id variant of SetCredentialsL
+	// will be removed.
+	iPlugin->SetCredentialsL( record.SIPSecUser(),
+	                          record.Realm(),
+                              *iOutboundProxy,
+                              iAuthorization->Response().iIMPI, // username
+                              KNullDesC8 ); // empty password ("")
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::Authorized
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::Authorized()
+    {    
+    RequestPassword();    
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::AuthorizationFailedL
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::AuthorizationFailedL()
+    {
+    __SIP_LOG( "SIPSecSIMCredProv:AuthorizationFailedL" )
+    __SIP_ASSERT_RETURN( iPlugin && iOutboundProxy, KErrNotFound );
+
+    CSIPSecSIMRecord& record = static_cast<CSIPSecSIMRecord&>( UserRecord() );
+
+    record.UserCredentialsFailed( CSIPSecSIMRecord::EPrivateIdentity );
+    iPlugin->SetCredentialsL( record.SIPSecUser(),
+                              record.Realm(),
+                              *iOutboundProxy,
+                              iAuthorization->Response().iIMPI,   // username
+                              iAuthentication->Response().iRES ); // password
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::PassErrorToFramework
+// If aAuthenticate == EFalse, UserCredentialsFailed( EPrivateIdentity ) has
+// already been done in AuthorizationFailedL.
+// ----------------------------------------------------------------------------
+//
+TInt CSIPSecSIMCredentialsProvider::PassErrorToFramework( TInt aError,
+	TBool aAuthenticate ) const
+	{
+	__SIP_ASSERT_RETURN_VALUE( iPlugin, KErrNotFound );
+
+	__SIP_INT_LOG2( "SIPSecSIMCredPr:PassErrorToFramework err, authen",
+	                aError,	aAuthenticate )
+
+	if ( aError == KErrNoMemory )
+		{
+		return aError;
+		}
+
+	CSIPSecSIMRecord& record = static_cast<CSIPSecSIMRecord&>( UserRecord() );
+
+	if ( aAuthenticate )
+		{		
+		// Sets state -> ECredentialsFailed and failure type -> ENoFailure
+		record.Invalidate( CSIPSecUserRecord::ECredentialsFailed );
+
+		// Sets failure type -> EPrivateIdentity. Does not change state.
+	    record.UserCredentialsFailed( CSIPSecSIMRecord::EPrivateIdentity );
+		}
+
+	// Inform SIPSecFW that the asynchronous request has ended
+	record.Updated();
+
+	// Don't remove anything from cache, but use CleanObservers
+	iPlugin->ClearCache( NULL );
+
+	return KErrNone;
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPSecSIMCredentialsProvider::HexDumpToLog
+// ----------------------------------------------------------------------------
+//
+void CSIPSecSIMCredentialsProvider::HexDumpToLog( const TDesC8& aMessage,
+												  const TDesC8& aData ) const
+	{
+	__SIP_DES8_LOG( "CSIPSecSIMCredentialsProvider::HexDumpToLog", aMessage )
+
+	// Prevent compiler warning in UREL build
+	aMessage.Length();
+
+	// Each byte uses 3 characters (e.g. 0x12 is written as "12 ")
+	const TInt KLengthOfByte = 3;
+	const TInt KMaxLineLength = 60;
+	TBuf8< KMaxLineLength > logBuf;
+
+	TInt inputPos( 0 );
+	while ( inputPos < aData.Length() )
+		{
+		logBuf.Zero();
+
+		TInt outputPos( 0 );
+		while ( ( outputPos < KMaxLineLength - KLengthOfByte ) &&
+		        ( inputPos < aData.Length() ) )
+			{
+			logBuf.AppendFormat( _L8( "%02x " ), aData[ inputPos++ ] );
+			outputPos += KLengthOfByte;
+			}
+		__SIP_DES8_LOG( "CSIPSecSIMCredentialsProvider::HexDumpToLog", logBuf )
+		}
+	}
+
+// End of File