smf/smfcredentialmgr/smfcredmgrserver/src/smfkeystoremanager.cpp
author cgandhi
Mon, 11 Oct 2010 21:59:54 +0530
changeset 26 83d6a149c755
parent 18 013a02bf2bb0
permissions -rw-r--r--
Submitting following changes - AuthApps for Last.fm and Twitter added API for checking ServiceAuthorization added for SMFCredMgrClient API added for forcefully removing credential details from SMFCredMgr Extra argument checks in SMfClient APIs APIs for service login and logout from SMFClient Redundant members removed from SmfServerSymbian DSM bug fixes Test Apps included

/**
 * Copyright (c) 2010 Sasken Communication Technologies Ltd.
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the "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:
 * Lasse Laasonen, Sasken Communication Technologies Ltd - Initial contribution
 *
 * Description:
 * This source contains routines handling RSA signing using Unified Key Store 
 */

#ifdef SYMBIAN_V3
#include <unifiedkeystore.h>
#include <asymmetric.h>
#include <mctkeystore.h>
#endif

#include <smfcredmgrclientdatastruct.h>
#include <smfcredmgrcommon.h>
#include <hash.h>

#include "smfkeystoremanager.h"

/**
 * NewL Method
 * @return The constructed CSmfKeyStoreManager instance
 */
CSmfKeyStoreManager* CSmfKeyStoreManager::NewL() {
	CSmfKeyStoreManager* self = CSmfKeyStoreManager::NewLC();
	CleanupStack::Pop( self );
	return self;
}

/**
 * NewLC Method
 * @return The constructed CSmfKeyStoreManager instance
 */
CSmfKeyStoreManager* CSmfKeyStoreManager::NewLC() {
	CSmfKeyStoreManager* self = new( ELeave )CSmfKeyStoreManager();
	CleanupStack::PushL( self );
	self->ConstructL();
	return self;
}

/**
 * Destructor
 */
CSmfKeyStoreManager::~CSmfKeyStoreManager() {
	iFs.Close();
	
	delete iSignParameters;
	iSignParameters = NULL;
	
	delete iRsaKeyParameters;
	iRsaKeyParameters = NULL;
	
}

/**
 * HandleMessageL
 * @param aMessage
 */
void CSmfKeyStoreManager::HandleMessageL( const RMessage2& aMessage ) 
	{
	RDebug::Printf("SMF: CSmfKeyStoreManager::HandleMessageL");
	iMessages.AppendL( &aMessage );
	if ( !IsActive() ) 
		{
		ContinueMessageHandlingL();
		}
	}

/**
 * RunL
 */
void CSmfKeyStoreManager::RunL() 
	{
	RDebug::Printf("SMF: CSmfKeyStoreManager::RunL, iStatus=%d", iStatus.Int() );
	
	switch( iState )
		{
		case EInitializingKeystore:
			{
			SetPassphraseTimeout();
			break;			
			}
		case ESettingPassphraseTimeout:
			{
			RDebug::Printf("SMF: Key store manager initialized");
			iState = EInitialized;
			break;
			}		
#ifdef SYMBIAN_V3
		case EGeneratingKey:
			{
			iState = EInitialized;
			RDebug::Printf("SMF: Completing generate key message");			
			iMessages[0]->Complete( iStatus.Int() );
			iMessages.Remove(0);
			break;
			}
		case EImportingKey:
			{
			iState = EInitialized;
			TInt num = iStatus.Int();
			if( iStatus.Int() == KErrNone ) 
				{
				iMessages[0]->WriteL( 1, iImportedKey->ID() );
				}
			
			RDebug::Printf("SMF: Completing import key message");
			iMessages[0]->Complete( iStatus.Int() );
			iMessages.Remove(0);
			break;
			}
		case EGettingKeyList:
		case EGettingRSASigner:
			{
			RSA_SHA1_SignMessageL();
			return;
			}
		case ERSASigningMessage:
			{
			iState = EInitialized;
			
			if ( iStatus.Int() == KErrNone ) 
				{
				HBufC8* signature = iRSASignature->S().BufferLC();
				RDebug::Printf("SMF: Signed message=%S", signature);			
				iMessages[0]->WriteL(1, *signature);			
				CleanupStack::PopAndDestroy();
				}
			iMessages[0]->Complete( iStatus.Int() );
			iMessages.Remove(0);
			break;
			}
		case EListingKeys:
			{
			iState = EInitialized;
			RDebug::Printf("Key count: %d", iKeys.Count() );
			for (TInt i = 0; i < iKeys.Count(); i++)
				{
				CCTKeyInfo* info = iKeys[i];
				RDebug::Printf("key label: %S", &info->Label());
				}
			iMessages[0]->Complete( iStatus.Int() );
			iMessages.Remove(0);
			break;
			}
		case EKeyDeleted:
			{
			iState = EInitialized;
			iMessages[0]->Complete(iStatus.Int());
			iMessages.Remove( 0 );
			break;
			}
		case EDeletingKey:
			{
			DeleteKeysL();
			break;
			}
#endif
		default:
			{
			break;
			}
		}
		
	if ( iMessages.Count() )
		{
		ContinueMessageHandlingL();
		}	
	}

/**
 * DoCancel
 */
void CSmfKeyStoreManager::DoCancel() {	
}

/**
 * RunError
 * @param aError
 * @return
 */
TInt CSmfKeyStoreManager::RunError( TInt aError ) {
	RDebug::Printf("SMF: CSmfKeyStoreManager::RunError error=%d", aError);
	
	if ( iMessages.Count() ) 
		{
		iMessages[0]->Complete( aError );
		iMessages.Remove( 0 );
		}

	return KErrNone;
}

/**
 * Constructor
 */
CSmfKeyStoreManager::CSmfKeyStoreManager() 
	:CActive(EPriorityStandard), iState(EInitializingKeystore) 
	{
	}

/**
 * Two-phase constructor
 */
void CSmfKeyStoreManager::ConstructL() {
	RDebug::Printf("SMF: CSmfKeyStoreManager::ConstructL");
	CActiveScheduler::Add( this );
#ifdef	SYMBIAN_V3
	User::LeaveIfError( iFs.Connect() );
	
	iKeyStore = CUnifiedKeyStore::NewL(iFs);
	iKeyStore->Initialize( iStatus );
	iState = EInitializingKeystore;
	SetActive();	
#endif
}

/**
 * ContinueMessageHandlingL
 */
void CSmfKeyStoreManager::ContinueMessageHandlingL() 
	{
	RDebug::Printf("SMF: CSmfKeyStoreManager::ContinueMessageHandling");
	
	if ( IsActive() )
		{
		return;
		}
	
	RMessage2* message = iMessages[0];
	TInt function = message->Function();
	
	switch( function ) 
		{
		case ESmfStoreRSAKey:
			{
			StoreRSAKeyL();
			break;
			}
		case ESmfRSASignMessage:
			{
			RSA_SHA1_SignMessageL();
			break;
			}
		case ESmfHMACSHA1SignMessage:
			{
			HMAC_SHA1_SignMessageL();
			break;
			}
		case ESmfDeleteKeys:
			{
			DeleteKeysL();
			break;
			}
		}
	}

/**
 * StoreRSAKeyL
 */
void CSmfKeyStoreManager::StoreRSAKeyL() 
	{
#ifdef SYMBIAN_V3
	RDebug::Printf("SMF: CSmfKeyStoreManager::StoreRSAKeyL");
	
	ReadRsaKeyParametersL();
	
	RDebug::Printf("SMF: Parameters read");
	
	iKeyStore->ImportKey(
			0, iRsaKeyParameters->KeyData(), EPKCS15UsageSign, iRsaKeyParameters->KeyName(),
			CCTKeyInfo::EExtractable, iRsaKeyParameters->StartDate(), iRsaKeyParameters->EndDate(),
			iImportedKey, iStatus );
	SetActive();
	iState = EImportingKey;
#endif
	}

/**
 * RSA_SHA1_SignMessageL
 */
void CSmfKeyStoreManager::RSA_SHA1_SignMessageL() 
	{
	
	RDebug::Printf("SMF: CSmfKeyStoreManager::RSA_SHA1_SignMessage");
#ifdef SYMBIAN_V3
	switch( iState ) 
		{
		case EInitialized:
			{
			// Get the key
			ReadSignParametersL(); 
			TCTKeyAttributeFilter filter;
			filter.iKeyAlgorithm = CCTKeyInfo::ERSA;
			
			iKeyStore->List( iKeys, filter, iStatus );
			iState = EGettingKeyList;
			SetActive();
			break;
			}
		case EGettingKeyList:
			{
			RDebug::Printf("SMF: key count=%d", iKeys.Count());
			// Find the correct key
			bool keyFound = EFalse;
			for( TInt i = 0; i < iKeys.Count(); i++ ) 
				{
			
				if ( iKeys[i]->ID() == iSignParameters->Key() ) 
					{
					RDebug::Printf("SMF: Correct key found");
					//might panic in CodeScanner, this open returns void
					iKeyStore->Open( *iKeys[i], iRSASigner, iStatus );
					iState = EGettingRSASigner;
					keyFound = ETrue;
					SetActive();
					break;						
					}
				}
			if ( !keyFound ) 
				{
				iMessages[0]->Complete( KErrNotFound );
				iMessages.Remove( 0 );
				}
			break;
			}
		case EGettingRSASigner:
			{
			ASSERT( iRSASigner != NULL );
			iRSASigner->SignMessage(iSignParameters->Message(), iRSASignature, iStatus);
			iState = ERSASigningMessage;
			SetActive();
			break;
			}
		default:
			{
			break;
			}
		}	
#endif
	}

/**
 * HMAC_SHA1_SignMessageL
 */
void CSmfKeyStoreManager::HMAC_SHA1_SignMessageL()
	{	
	ReadSignParametersL();
	
	RDebug::Printf("SMF: CSmfKeyStoreManager::HMAC_SHA1_SignMessage");
	
	CSHA1* sha = CSHA1::NewL();
	CHMAC* hmac = CHMAC::NewL( iSignParameters->Key(), sha );
	TPtrC8 hashedSig( hmac->Hash( iSignParameters->Message() ) );
	
	RDebug::Printf("SMF: hashed message length=%d", hashedSig.Length());
	RDebug::Printf("SMF: hashed message=%S", &hashedSig);
	
	iMessages[0]->WriteL( 1, hashedSig );
	
	RDebug::Printf("SMF: result written");
	
	iMessages[0]->Complete( KErrNone );
	iMessages.Remove(0);
	
	RDebug::Printf("SMF: message completed");
	
	delete iSignParameters;
	iSignParameters = NULL;	
	}

/**
 * DeleteKeysL
 */
void CSmfKeyStoreManager::DeleteKeysL() 
	{
	RDebug::Printf("SMF: CSmfKeyStoreManager::DeleteKeys");
#ifdef SYMBIAN_V3
	switch ( iState ) 
		{
		case EInitialized:
			{
			iKeys.Reset();
			TCTKeyAttributeFilter filter;
			filter.iKeyAlgorithm = CCTKeyInfo::ERSA;
			iKeyStore->List( iKeys, filter, iStatus );
			iState = EDeletingKey;
			SetActive();
			break;
			}
		case EDeletingKey:
			{
			RDebug::Printf("SMF: key count=%d", iKeys.Count());
			//read the key-label to delete from message
			HBufC* KeyBuf = HBufC::NewL(KMaxSignedMsgLength);
			TPtr keyPtr(KeyBuf->Des());
			iMessages[0]->Read(0, keyPtr);

			// Find the correct key
			bool keyFound = EFalse;
			for (TInt i = 0; i < iKeys.Count(); i++)
				{
				if (iKeys[i]->ID() == (keyPtr.Collapse()))
					{
					RDebug::Printf("SMF: Correct key found");
					iKeyStore->DeleteKey(*iKeys[i], iStatus);
					keyFound = ETrue;
					iState = EKeyDeleted;
					SetActive();
					}
				}
			if (!keyFound)
				{
				iMessages[0]->Complete(KErrNotFound);
				iMessages.Remove( 0 );
				}
			
			
			break;
			}
		}
#endif
	}

/**
 * SetPassphraseTimeout
 */
void CSmfKeyStoreManager::SetPassphraseTimeout() 
	{
#ifdef SYMBIAN_V3
	iKeyStore->SetPassphraseTimeout( -1, iStatus );
	iState = ESettingPassphraseTimeout;
	SetActive();
#endif
	}

/**
 * ReadSignParametersL
 */
void CSmfKeyStoreManager::ReadSignParametersL()
	{
	RMessage2* message = iMessages[0];
	RBuf8 dataBuf;
	CleanupClosePushL( dataBuf );
	dataBuf.CreateL( message->GetDesLength( 0 ) );
	message->ReadL( 0, dataBuf, 0 );

	delete iSignParameters;
	iSignParameters = NULL;
	
	iSignParameters = CSmfSignParameters::NewL( dataBuf );
	
	CleanupStack::PopAndDestroy( &dataBuf );
	}

/**
 * ReadRsaKeyParametersL
 */
void CSmfKeyStoreManager::ReadRsaKeyParametersL()
	{
	RMessage2* message = iMessages[0];

	RBuf8 dataBuf;
	CleanupClosePushL( dataBuf );
	dataBuf.CreateL( message->GetDesLength( 0 ) );
	message->ReadL( 0, dataBuf, 0 );

	delete iRsaKeyParameters;
	iRsaKeyParameters = NULL;
	
	iRsaKeyParameters = CSmfRsaKeyParameters::NewL( dataBuf );
	
	CleanupStack::PopAndDestroy( &dataBuf );
	}