smf/smfcredentialmgr/smfcredmgrserver/src/smfkeystoremanager.cpp
author cgandhi <chandradeep.gandhi@sasken.com>
Wed, 23 Jun 2010 19:51:49 +0530
changeset 14 a469c0e6e7fb
child 18 013a02bf2bb0
permissions -rw-r--r--
changes for SmfPost, SmfCredentialMgr, PLuginManager, SmfServer. Adding Sample Plugins and Sample Client Applications.

/**
 * 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"

CSmfKeyStoreManager* CSmfKeyStoreManager::NewL() {
	CSmfKeyStoreManager* self = CSmfKeyStoreManager::NewLC();
	CleanupStack::Pop( self );
	return self;
}

CSmfKeyStoreManager* CSmfKeyStoreManager::NewLC() {
	CSmfKeyStoreManager* self = new( ELeave )CSmfKeyStoreManager();
	CleanupStack::PushL( self );
	self->ConstructL();
	return self;
}

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

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

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:
			{
			DeleteKeys();
			break;
			}
#endif
		default:
			{
			break;
			}
		}
		
	if ( iMessages.Count() )
		{
		ContinueMessageHandlingL();
		}	
	}

void CSmfKeyStoreManager::DoCancel() {	
}

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;
}

CSmfKeyStoreManager::CSmfKeyStoreManager() 
	:CActive(EPriorityStandard), iState(EInitializingKeystore) 
	{
	}

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
}

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:
			{
			DeleteKeys();
			break;
			}
		}
	}

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
	}

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");
					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
	}

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;	
	}

void CSmfKeyStoreManager::DeleteKeys() 
	{
	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
	}

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

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 );
	}

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 );
	}