policymanagement/policyengine/policyengineserver/src/TrustedSession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 14 Apr 2010 16:50:34 +0300
branchRCL_3
changeset 21 504e41245867
parent 0 b497e44ab2fc
child 34 696f5dd11939
permissions -rw-r--r--
Revision: 201013 Kit: 201015

/*
* Copyright (c) 2002-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 policymanagement components
*
*/


// INCLUDE FILES

#include "TrustedSession.h"
#include "XACMLconstants.h"
#include "PolicyEngineServer.h"
#include "PolicyParser.h"
#include "elements.h"
#include "DataTypes.h"
#include "debug.h"
#include "ErrorCodes.h"

#include <x509cert.h>
#include <tconvbase64.h>



const TChar KCASNDelimeter = '-';
_LIT( KSecureIdString, "SECUREID");


CTrustedSession::CTrustedSession()
	: iSessionTrust( EFalse)
{
}

// -----------------------------------------------------------------------------
// CTrustedSession::~CTrustedSession()
// -----------------------------------------------------------------------------
//

CTrustedSession::~CTrustedSession()
{
	delete iCASN;
}



// -----------------------------------------------------------------------------
// CTrustedSession::NewL()
// -----------------------------------------------------------------------------
//

CTrustedSession * CTrustedSession::NewL()
{
	CTrustedSession * self = new(ELeave) CTrustedSession();
	return self;
}

// -----------------------------------------------------------------------------
// CTrustedSession::IsSessionCertificated()
// -----------------------------------------------------------------------------
//
void CTrustedSession::MakeSessionTrustL( const RMessage2& aMessage)
{
	RDEBUG( "Policy Engine: Creating session trust");

	if ( iSessionTrust )
	{
		User::Leave( KErrAlreadyExists);
	}

	//Read certificate info to member
	TPckg<TCertInfo> certInfoPack( iSessionCertInfo);
	aMessage.ReadL(0, certInfoPack, 0);	

	//turn session trust on
	iSessionTrust = ETrue;	

	RDEBUG( "Policy Engine: Session trust created");

}


// -----------------------------------------------------------------------------
// CTrustedSession::IsSessionCertificated()
// -----------------------------------------------------------------------------
//
void CTrustedSession::RemoveSessionTrust()
{
	iSessionTrust = EFalse;
	delete iCASN;
	iCASN = NULL;
}


// -----------------------------------------------------------------------------
// CTrustedSession::IsSessionCertificated()
// -----------------------------------------------------------------------------
//
TCertInfo& CTrustedSession::SessionCertificate()
{
	return iSessionCertInfo;
}



// -----------------------------------------------------------------------------
// CTrustedSession::IsSessionCertificated()
// -----------------------------------------------------------------------------
//

TBool CTrustedSession::CertificatedSession() const
{
	return iSessionTrust;
}




// -----------------------------------------------------------------------------
// CTrustedSession::CASNForSessionL()
// -----------------------------------------------------------------------------
//

const TDesC8& CTrustedSession::CASNForSessionL()
{
	RDEBUG("PolicyEngineServer: CTrustedSession::CASNForSession");

	if ( !iCASN )
	{
		iCASN =	CCertificateMaps::CasnForCertInfoL( iSessionCertInfo );
	}
	
	RDEBUG8_2("PolicyEngineServer: Session CASN: %S", iCASN);
	return *iCASN;
}

// -----------------------------------------------------------------------------
// CTrustedSession::GetMappedTargetTrustedSubjectL()
// -----------------------------------------------------------------------------
//
void CTrustedSession::GetMappedTargetTrustedSubjectL(
	RPointerArray<HBufC8>& aTargetTrustedMappedSubjectArray, 
	CElementBase * aElement, TBool aUseEditedItems )
	{	
	RElementArray attributes;	
	CleanupClosePushL( attributes );
	aElement->FindAttributesL( ESubjectMatch, attributes );
	
	for( TInt i(0); i < attributes.Count(); i++ )
		{
		CMatchObject * matchObject = (CMatchObject*)attributes[ i ];		
		TElementReserver reserver( matchObject );
		CPolicyStorage::PolicyStorage()->CheckElementL( matchObject );
		
		//get attribute ids
		TDesC8& subjectAtt = matchObject->AttributeDesignator()->GetAttributeid();
		TDesC8& value = matchObject->AttributeValue()->Data()->Value();
		
		if( subjectAtt == PolicyEngineXACML::KCertificateMapped )
			{
			//Create new subject info
			CCertificateMaps::CSubjectInfo* tempInfo = new (ELeave) CCertificateMaps::CSubjectInfo();
			CleanupStack::PushL( tempInfo );
			
			//create suject info for it
			CCertificateMaps::CreateSubjectInfoL( tempInfo, value );

			//Search corresponding subject info from certificate storage
			HBufC8* casn = tempInfo->iCASN->AllocL();
			CleanupStack::PushL( casn );
			// do not delete info object
			CCertificateMaps::CSubjectInfo* info = CPolicyEngineServer::CertificateMaps()->FindSubjectL( *casn, aUseEditedItems );		
			
			if( info )
				{
				HBufC8* temp = info->iCASN->AllocL();
				aTargetTrustedMappedSubjectArray.Append( temp );
				}
			
			CleanupStack::PopAndDestroy( casn );
			CleanupStack::PopAndDestroy( tempInfo );
			}
		}

	CleanupStack::PopAndDestroy( &attributes );
	}

// -----------------------------------------------------------------------------
// CTrustedSession::GetTargetTrustedSubjectL()
// -----------------------------------------------------------------------------
//
HBufC8* CTrustedSession::GetTargetTrustedSubjectL( 
	CElementBase * aElement, TBool aUseEditedItems )
	{
	//find alias for certificate, find policy subjects
	RElementArray attributes;	
	CleanupClosePushL( attributes );
	aElement->FindAttributesL( ESubjectMatch, attributes );
	
	HBufC8* retVal = 0;
	
	for( TInt i(0); i < attributes.Count(); i++ )
		{
		CMatchObject * matchObject = (CMatchObject*)attributes[ i ];		
		TElementReserver reserver( matchObject );
		CPolicyStorage::PolicyStorage()->CheckElementL( matchObject );

		//get attribute ids
		TDesC8& subjectAtt = matchObject->AttributeDesignator()->GetAttributeid();
		TDesC8& value = matchObject->AttributeValue()->Data()->Value();

		//tempvalue contain trusted subject value (CASN or alias)
		HBufC8* tempValue = 0;
		
		if( subjectAtt == PolicyEngineXACML::KCertificate )
			{
			//Create new subject info
			CCertificateMaps::CSubjectInfo* tempInfo = new (ELeave) CCertificateMaps::CSubjectInfo();
			CleanupStack::PushL( tempInfo);
			
			//create suject info for it
			CCertificateMaps::CreateSubjectInfoL( tempInfo, value);

			//Search corresponding subject info from certificate storage
			tempValue = tempInfo->iCASN->AllocL();
			
			CleanupStack::PopAndDestroy( tempInfo );			 
			}
		else if( subjectAtt == PolicyLanguage::Constants::AutoCertificate )
			{
			//Create new subject info
			CCertificateMaps::CSubjectInfo* tempInfo = new (ELeave) CCertificateMaps::CSubjectInfo();
			CleanupStack::PushL( tempInfo );

			TCertInfo certInfo;
			TPckg<TCertInfo> pck( certInfo );
	
			TBase64 base64;
			User::LeaveIfError( base64.Decode( value, pck ) );	
				
			//create suject info for it
			CCertificateMaps::CreateSubjectInfoL( tempInfo, certInfo );

			//Search corresponding subject info from certificate storage
			tempValue = tempInfo->iCASN->AllocL();
			
			CleanupStack::PopAndDestroy( tempInfo );			
			}
		else if( subjectAtt == PolicyEngineXACML::KTrustedSubject)
			{
			tempValue = value.AllocL();
			}

		//evaluate temp value
		if( tempValue )
			{
			//Search corresponding subject info from certificate storage
			CCertificateMaps::CSubjectInfo* info = CPolicyEngineServer::CertificateMaps()->FindSubjectL( *tempValue, aUseEditedItems );		

			//if corresponding info found, realloc tempvalue with info->iCASN value			
			if( info )
				{
				delete tempValue;
				tempValue = NULL;
				tempValue = info->iCASN->AllocL();
				}			

			if( retVal )
				{
				//if retVal already exists and temp value doesn't match, break, delete buffers and set null to retval
				if ( *retVal != *tempValue )
					{
					delete retVal;
					retVal = 0;
					break;
					} 
				}
			else
				{
				//if retVal is not exist yet, create new one
				retVal = tempValue->AllocL();
				}
		
			delete tempValue;
			}
		}

	CleanupStack::PopAndDestroy( &attributes );
	return retVal;
	}



// -----------------------------------------------------------------------------
// CTrustedSession::IsCertificateMappingValidL()
// -----------------------------------------------------------------------------
//

TBool CTrustedSession::IsCertificateMappingValidL( CElementBase * aElement)
{
	//element is parsed and must be valid 
	__ASSERT_ALWAYS ( aElement, User::Panic(Panics::TrustedSessionManagerPanic, KErrCorrupt));

	//element type must be rule
	if ( aElement->ElementType() != ERule)
	{
		return EFalse;
	}
	


	CTarget * target = ((CRule*)aElement)->GetTarget();
	if ( !target)
	{
		return EFalse;
	}
	
	//Mapping rule target contains allways one CSubjects element
	if ( target->SubElementType( 0, 1) != ESubjects )
	{
		return EFalse;
	}
	
	CSubjects * subjects = (CSubjects*)target->Element(0);

	//Mapping subjects contains allways one CSubject element
	if ( subjects->SubElementType( 0, 1) != ESubject )
	{
		return EFalse;
	}
	
	CSubject * subject = (CSubject*)subjects->Element(0);

	//element type should be subjectmatch in all cases!
	if ( subject->SubElementType( 0, 2) != ESubjectMatch || 
		 subject->SubElementType( 1) != ESubjectMatch )
		{
			return EFalse;
		}
	
	
	//Get match objects
	CMatchObject* subject1 = (CMatchObject*) subject->Element(0);
	CMatchObject* subject2 = (CMatchObject*) subject->Element(1);
			
	//get attribute ids
	TDesC8& subjectAtt1 = subject1->AttributeDesignator()->GetAttributeid();
	TDesC8& subjectAtt2 = subject2->AttributeDesignator()->GetAttributeid();
			
	//certificate -> alias mapping
	if ( subjectAtt1 == PolicyEngineXACML::KCertificate && subjectAtt2 == PolicyEngineXACML::KAliasId)
	{
		CPolicyEngineServer::CertificateMaps()->BringUpToDateL();
	
		//Check that new alias is not already exist
		if ( CPolicyEngineServer::CertificateMaps()->IsAliasExistL( subject2->AttributeValue()->Data()->Value()))
		{
			return EFalse;
		}
		
		TDesC8& certificateValue = subject1->AttributeValue()->Data()->Value();
		
		//Leaves if certificate is not valid, otherwise just delete certificate
		CX509Certificate * cert = CCertificateMaps::ParseCertificateL( certificateValue); 
		delete cert;
			
		return ETrue;
	} 

	//certificate -> new certificate (certificate )
	if ( subjectAtt1 == PolicyEngineXACML::KCertificate && subjectAtt2 == PolicyEngineXACML::KCertificateMapped)
	{
		TDesC8& certificateValue = subject1->AttributeValue()->Data()->Value();
		TDesC8& certificateValueMapped = subject2->AttributeValue()->Data()->Value();

		//Leaves if certificate is not valid, otherwise just delete certificate
		CX509Certificate * cert = CCertificateMaps::ParseCertificateL( certificateValue); 
		delete cert;
		CX509Certificate * certMapped = CCertificateMaps::ParseCertificateL( certificateValueMapped); 
		delete certMapped;


		return ETrue;
	} 
	
	return EFalse;
}

// -----------------------------------------------------------------------------
// CTrustedSession::AddCertificateMappingL()
// -----------------------------------------------------------------------------
//
CElementBase* CTrustedSession::CreateCertificateMappingL( const TDesC8& aAlias )
{
	using namespace PolicyLanguage::Constants;
	using namespace PolicyLanguage::NativeLanguage;

	//Check that alias is valid (not allready exists)
	if ( CPolicyEngineServer::CertificateMaps()->IsAliasExistL( aAlias))
	{
		return 0;
	}
	
	//Ensures that CASN is valid...
	CASNForSessionL();
	
	//Create new mapping policy
	//first create id for new rule, format is auto_certificate+CASN
	HBufC8 * extId = HBufC8::NewLC( AutoCertificateLength + iCASN->Length() + 1);
	TPtr8 extIdPtr = extId->Des();
	
	extIdPtr.Append( AutoCertificate);
	extIdPtr.Append( '_');
	extIdPtr.Append( *iCASN);
	
	ReplaceIllegalCharacters( extIdPtr );
	
	//Check id
	if ( !CPolicyStorage::PolicyStorage()->IsRealIdValidL( extIdPtr))
	{
		CleanupStack::PopAndDestroy( extId);
		return 0;
	}
		
	//and assign rule to element
	CRule *rule = CRule::NewL();

	CleanupStack::PushL( rule);
	rule->SetRuleIdL( extIdPtr);
	rule->SetEffectL( Rule::Permit);
	
	//target
	CTarget * target = CTarget::NewL();
	CleanupStack::PushL( target);
	rule->AddElementL( 0, target);
	CleanupStack::Pop( target);
	
	//subjects
	CSubjects * subjects = CSubjects::NewL();
	CleanupStack::PushL( subjects );
	target->AddElementL( 0, subjects);
	CleanupStack::Pop( subjects );

	//subject
	CSubject * subject = CSubject::NewL();
	CleanupStack::PushL( subject );
	subjects->AddToElementListL( subject , ETrue);
	CleanupStack::Pop( subject );
	
	
	//first subjectmatch
	CMatchObject * match = new (ELeave) CMatchObject( ESubjectMatch);
	subject->AddToElementListL( match, ETrue);
	
	match->AddAttributeL( 0, MatchObject::MatchId, 
							 Functions::FunctionStringEqualId);
	
	//designator and value for certificate
	CSubjectAttributeDesignator * designator = CSubjectAttributeDesignator::NewL();
	match->AddElementL( 0, designator);
	designator->AddAttributeL( 0, AttributeDesignators::AttributeId, AutoCertificate);
	designator->AddAttributeL( 0, AttributeDesignators::DataType, PolicyLanguage::NativeLanguage::AttributeValues::StringDataType);
	
	//serialize TCertInfo and decode it to base64 format
	TPckg<TCertInfo> pck( iSessionCertInfo);
	TBase64 base64;
	HBufC8 * base64coded = HBufC8::NewLC( pck.Length() * 3);
	TPtr8 base64Ptr = base64coded->Des();
	User::LeaveIfError( base64.Encode( pck, base64Ptr));	

	CAttributeValue * aliasValue = CAttributeValue::NewL( base64Ptr, PolicyLanguage::NativeLanguage::AttributeValues::StringDataType);
	CleanupStack::PopAndDestroy( base64coded);
		
	match->AddElementL( 0, aliasValue);
	
	//second subjectmatch
	match = new (ELeave) CMatchObject( ESubjectMatch);
	subject->AddToElementListL( match, ETrue);
	
	match->AddAttributeL( 0, MatchObject::MatchId, 
							 Functions::FunctionStringEqualId);


	//designator and value for alias
	designator = CSubjectAttributeDesignator::NewL();
	match->AddElementL( 0, designator);
	designator->AddAttributeL( 0, AttributeDesignators::AttributeId, PolicyEngineXACML::KAliasId);
	designator->AddAttributeL( 0, AttributeDesignators::DataType, PolicyLanguage::NativeLanguage::AttributeValues::StringDataType);
	
	aliasValue = CAttributeValue::NewL( aAlias, PolicyLanguage::NativeLanguage::AttributeValues::StringDataType);
	match->AddElementL( 0, aliasValue);
	
	
	//Destroy objects....
	CleanupStack::Pop( rule);
	CleanupStack::PopAndDestroy( extId);
	
	
	return rule;
}


void CTrustedSession::ReplaceIllegalCharacters( TPtr8& aData )
	{
	RDEBUG("CTrustedSession::ReplaceIllegalCharacters()");
	
	TChar char1('/');
	TBuf8<10> buf;
	buf.Append( _L("_") );
	for(TInt i = 0;;i++)
		{
		TInt index = aData.Locate( char1 );
		if( index > KErrNotFound )
			{
			aData.Replace( index, 1, buf );
			}
		else
			{
			break;
			}
		}
	
	}

// -----------------------------------------------------------------------------
// CTrustedSession::CommonNameForSubject()
// -----------------------------------------------------------------------------
//

const TDesC8& CTrustedSession::CommonNameForSubjectL( const TDesC8& aTrustedSubject, TBool aUseEditedItems )
{
	RDEBUG("PolicyEngineServer: CTrustedSession::CommonNameForSubjectL");

	//ensures that iCASN is valid
	CASNForSessionL();
	
	if ( aTrustedSubject == *iCASN )
	{
		return iSessionCertInfo.iSubjectDNInfo.iCommonName;
	}
	
	CPolicyEngineServer::CertificateMaps()->BringUpToDateL();
	CCertificateMaps::CSubjectInfo* info = CPolicyEngineServer::CertificateMaps()->FindSubjectL( aTrustedSubject, aUseEditedItems);

	
	if (info)
	{
		return *info->iSubject;
	}
	
	return KNullDesC8;
}

// -----------------------------------------------------------------------------
// CTrustedSession::FingerPrintForSubject()
// -----------------------------------------------------------------------------
//


const TDesC8& CTrustedSession::FingerPrintForSubjectL( const TDesC8& aTrustedSubject, TBool aUseEditedItems)
{
	RDEBUG("PolicyEngineServer: CTrustedSession::CommonNameForSubjectL");

	//ensures that iCASN is valid
	CASNForSessionL();
	
	if ( aTrustedSubject == *iCASN )
	{
		//get finger print
		iFingerPrint.Zero();

		//convert fingerprint to plain text
		for ( TInt i(0); i < iSessionCertInfo.iFingerprint.Length(); i++)
		{
			iFingerPrint.AppendNum( iSessionCertInfo.iFingerprint[i], EHex);
		}		
		
		return iFingerPrint;
	}
	
	CPolicyEngineServer::CertificateMaps()->BringUpToDateL();
	CCertificateMaps::CSubjectInfo* info = CPolicyEngineServer::CertificateMaps()->FindSubjectL( aTrustedSubject, aUseEditedItems);
	
	if (info)
	{
		return *info->iFingerPrint;
	}
	
	return KNullDesC8;
}



// -----------------------------------------------------------------------------
// CTrustedSession::AddSessionSIDL()
// -----------------------------------------------------------------------------
//

void CTrustedSession::AddSessionSIDL( TUid aSecirityUID)
{
	//add SECUREID start mark
	iSessionSID.Zero();
	iSessionSID.Append( KSecureIdString);	
	iSessionSID.Append( aSecirityUID.Name());
	iSessionSID.UpperCase();
	
}


// -----------------------------------------------------------------------------
// CTrustedSession::SIDForSession()
// -----------------------------------------------------------------------------
//

const TDesC8& CTrustedSession::SIDForSession()
{
	return iSessionSID;
}


// -----------------------------------------------------------------------------
// CTrustedSession::CertMatchL()
// -----------------------------------------------------------------------------
//
TBool CTrustedSession::CertMatchL( const TDesC8& aTrustedSubject1, const TDesC8& aTrustedSubject2, TBool /*aUseEditedItems*/ )
{
	TBool subjectMatch = EFalse;
	
	CCertificateMaps * maps = CPolicyEngineServer::CertificateMaps();
	maps->BringUpToDateL();


	//find subject info for asubject
	for ( TInt i = 0; i < maps->iCerts.Count(); i++)
	{
		CCertificateMaps::CSubjectInfo* info = maps->iCerts[i];
		
		 
		if ( info->Match( aTrustedSubject1, ETrue) && info->Match( aTrustedSubject2, ETrue))
		{
			//subject1 and subject2 are same instance!!
			subjectMatch = ETrue;
			break;	
		}
		
	}
	
	return subjectMatch;
}

// -----------------------------------------------------------------------------
// CTrustedSession::RoleMatchL()
// -----------------------------------------------------------------------------
//
TBool CTrustedSession::RoleMatchL( const TDesC8& aTrustedSubject, const TDesC8& aRole, TBool aUseEditedItems )
{
	//find subject info for asubject
	CCertificateMaps * cerMaps = CPolicyEngineServer::CertificateMaps();
	cerMaps->BringUpToDateL();

	TBool validRole = EFalse;
	
	for ( TInt i(0); i < cerMaps->iCerts.Count(); i++)
	{
		CCertificateMaps::CSubjectInfo* info = cerMaps->iCerts[i];
		
		if ( !CCertificateMaps::EvaluateElementValidity( aUseEditedItems, info->iState))
		{
			continue;
		}		
		
		if ( info->Match( aTrustedSubject, ETrue) && info->RoleMatchL( aRole))
		{
			//aRole is valid role for aTrustedSubject!!
			validRole = ETrue;
			break;
		}
	}
	
	
	return validRole;
}
		

// -----------------------------------------------------------------------------
// CCertificateMaps::CRolesInfo::CRolesInfo()
// -----------------------------------------------------------------------------
//
CCertificateMaps::CRolesInfo::CRolesInfo()
{
}


// -----------------------------------------------------------------------------
// CCertificateMaps::CRolesInfo::~CRolesInfo()
// -----------------------------------------------------------------------------
//
CCertificateMaps::CRolesInfo::~CRolesInfo()
{
	delete iRole;
}


// -----------------------------------------------------------------------------
// CCertificateMaps::CRolesInfo::NewL()
// -----------------------------------------------------------------------------
//
CCertificateMaps::CRolesInfo* CCertificateMaps::CRolesInfo::NewL( const TDesC8& aRole, TElementState aState)
{
	CRolesInfo * self = new (ELeave) CRolesInfo();
	
	self->iRole = aRole.AllocL();
	self->iState = aState;
	
	return self;
}

// -----------------------------------------------------------------------------
// CCertificateMaps::CSubjectInfo::CSubjectInfo()
// -----------------------------------------------------------------------------
//

CCertificateMaps::CSubjectInfo::CSubjectInfo()
{
}

// -----------------------------------------------------------------------------
// CCertificateMaps::CSubjectInfo::~CSubjectInfo()
// -----------------------------------------------------------------------------
//

CCertificateMaps::CSubjectInfo::~CSubjectInfo()
{
	delete iCASN;			
	delete iMappedToCert;		
	delete iAlias;			
	delete iSubject;		
	delete iFingerPrint;	
	iRoles.ResetAndDestroy();
	iRoles.Close();
}

// -----------------------------------------------------------------------------
// CCertificateMaps::CSubjectInfo::~CSubjectInfo()
// -----------------------------------------------------------------------------
//
TBool CCertificateMaps::CSubjectInfo::RoleMatchL( const TDesC8& aRole)
{
	TBool retVal = EFalse;

	//find roles from this subject match
	for ( TInt i(0); i < iRoles.Count(); i++)
	{
		CRolesInfo * info = iRoles[i];
		
		if ( aRole.CompareF( *info->iRole)  == 0)
		{
			retVal = ETrue;
			break;
		}
	}
	
	//and if needed check also mappedtoinfo
	if ( !retVal && iMappedToInfo)
	{
		retVal = iMappedToInfo->RoleMatchL( aRole);
	}
	
	return retVal;
}

// -----------------------------------------------------------------------------
// CCertificateMaps::CSubjectInfo::~CSubjectInfo()
// -----------------------------------------------------------------------------
//
TBool CCertificateMaps::CSubjectInfo::Match( const TDesC8& aTrustedSubject, TBool aCheckMappedCertificates)
{
	//Check CASN
	if ( iCASN )
	{
		if ( aTrustedSubject.CompareF(  *iCASN)  == 0 )
		{
			return ETrue;
		}
	}

	//Check alias
	if ( iAlias )
	{
		if ( aTrustedSubject.CompareF( *iAlias ) == 0)
		{
			return ETrue;
		}
	}
	
	if ( aCheckMappedCertificates && iMappedToInfo )
	{
		return iMappedToInfo->Match( aTrustedSubject, ETrue);
	}

	return EFalse;	
}


TRole CCertificateMaps::CSubjectInfo::CertificateRoleL( TBool aUseEditedItems )
	{
	TPtr8 ptr = iFingerPrint->Des();
	RDEBUG8_2("CSubjectInfo::CertificateRoleL() (fingerprint: %S)", &ptr );
	
	TRole retVal( ENoRole );
	
	RDEBUG8_2("	-> this certificate has %d roles", iRoles.Count() );
	for( TInt j(0); iRoles.Count(); j++ )
		{
		CRolesInfo* role = iRoles[ j ];
		
		//accept only elements which are committed...
		if( !EvaluateElementValidity( aUseEditedItems, role->iState ) )
			{
			RDEBUG("	-> found invalid element from CRolesInfo");
			continue;
			}			
		
		if( *role->iRole == PolicyEngineXACML::KRoleCorporate )
			{
			RDEBUG("	-> found KRoleCorporate");
			retVal = ECorporateRole;
			break;	
			}
		}
	
	if( ( retVal == ENoRole ) && iMappedToInfo )
		{
		RDEBUG("	-> -> searching KRoleCorporate from certificate mappings recursively .. ");
		retVal = iMappedToInfo->CertificateRoleL( aUseEditedItems );
		RDEBUG("	<- <- searching KRoleCorporate from certificate mappings recursively .. DONE");
		}
	else if( ( retVal == ENoRole ) && !iMappedToInfo )
		{
		RDEBUG("	-> not mapped - can not search recursively");
		}
		
	return retVal;
	}


// -----------------------------------------------------------------------------
// CCertificateMaps::CCertificateMaps()
// -----------------------------------------------------------------------------
//
CCertificateMaps::CCertificateMaps()
{
	iPolicyStorage = CPolicyStorage::PolicyStorage();
	iMapsUpToDate = EFalse;
}

// -----------------------------------------------------------------------------
// CCertificateMaps::~CCertificateMaps()
// -----------------------------------------------------------------------------
//
CCertificateMaps::~CCertificateMaps()
{
	iCerts.ResetAndDestroy();
	iCerts.Close();
}

CCertificateMaps* CCertificateMaps::NewL()
{
	CCertificateMaps* self = new (ELeave) CCertificateMaps();
	
	CleanupStack::PushL( self);
	CleanupStack::Pop( self);
	
	return self;	
}

// -----------------------------------------------------------------------------
// CCertificateMaps::LoadCertificateMaps()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::LoadCertificateMapsL()
{
	RDEBUG("CCertificateMaps::LoadCertificateMaps");

	iCerts.ResetAndDestroy();

	using namespace PolicyLanguage::Constants;
	using namespace PolicyEngineXACML;

	//get Certificate mapping policy from storage (get also edited elements)
	CElementBase * aliasPolicy = iPolicyStorage->GetEditableElementL( CertMappingPolicy);

	//if eleemnt is not valid
	if ( !aliasPolicy)
	{
		return;
	}
		
	//reserve and load element
	TElementReserver certReserver( aliasPolicy);
	iPolicyStorage->CheckElementL( aliasPolicy);

	//find alias for certificate, find policy subjects
	RElementArray attributes;	
	CleanupClosePushL( attributes);
	aliasPolicy->FindAttributesL( ESubject, attributes);


	for ( TInt i = 0; i < attributes.Count(); i++)
	{
		CElementBase * element = attributes[i];
		
		//only two subjectmatch allowed
		if ( element->ElementType() == ESubject && element->ElementCount() == 2 )
		{
			//element type should be subjectmatch in all cases!
			__ASSERT_ALWAYS ( element->Element(0)->ElementType() == ESubjectMatch, User::Panic(Panics::TrustedSessionManagerPanic, KErrCorrupt));
			__ASSERT_ALWAYS ( element->Element(1)->ElementType() == ESubjectMatch, User::Panic(Panics::TrustedSessionManagerPanic, KErrCorrupt));

			//Get match objects, reserve and load them
			CMatchObject* subject1 = (CMatchObject*) element->Element(0);
			CMatchObject* subject2 = (CMatchObject*) element->Element(1);
			
			TElementReserver reserver1( subject1);
			TElementReserver reserver2( subject2);
			iPolicyStorage->CheckElementL( subject1);
			iPolicyStorage->CheckElementL( subject2);
			
			//get attribute ids
			TDesC8& subjectAtt1 = subject1->AttributeDesignator()->GetAttributeid();
			TDesC8& subjectAtt2 = subject2->AttributeDesignator()->GetAttributeid();
			
			//Create new subject info
			CSubjectInfo* info = new (ELeave) CSubjectInfo();
			CleanupStack::PushL( info);
			
			//set committed state flag
			info->iState = element->iElementState;

			//certificate -> alias mapping
			if ( subjectAtt1 == KCertificate && subjectAtt2 == KAliasId)
			{
				RDEBUG("PolicyEngineServer: Certificate mapped to Alias");
			
				//get attribute value and parse certificate
				TDesC8& binaryCert = subject1->AttributeValue()->Data()->Value();
				
				//create suject info for it
				CreateSubjectInfoL( info, binaryCert);
					
				TDesC8& alias = subject2->AttributeValue()->Data()->Value();
				info->iAlias = alias.AllocL();

				RDEBUG8_3("PolicyEngineServer: Certificate mapped: %S -> %S", info->iCASN, info->iAlias);

				iCerts.AppendL( info);
				CleanupStack::Pop( info);
			}
			else if ( subjectAtt1 == KCertificate && subjectAtt2 == KCertificateMapped)
			{
				RDEBUG("PolicyEngineServer: Certificate mapped to new certificate");
		
				//get attribute values....
				TDesC8& binaryOldCert = subject1->AttributeValue()->Data()->Value();
				TDesC8& binaryNewCert = subject2->AttributeValue()->Data()->Value();

				//create subject info for new certificate mapping
				CreateSubjectInfoL( info, binaryNewCert);

				//create subject info for mapped certificate
				CSubjectInfo* mappingInfo = new (ELeave) CSubjectInfo();
				CleanupStack::PushL( mappingInfo);
				CreateSubjectInfoL( mappingInfo, binaryOldCert);
				
				//add the mapping info to new certificate 
				info->iMappedToCert = mappingInfo->iCASN->AllocL();
				CleanupStack::PopAndDestroy( mappingInfo);

				iCerts.AppendL( info);
				CleanupStack::Pop( info);
			}
			else if  ( subjectAtt1 == AutoCertificate && subjectAtt2 == KAliasId)
			{
				RDEBUG("PolicyEngineServer: Certificate mapped to Alias");
			
				//get attribute value and parse certificate info ( base64 -> serialization -> TCertInfo)
				TDesC8& binaryCert = subject1->AttributeValue()->Data()->Value();
				
				TCertInfo certInfo;
				TPckg<TCertInfo> pck( certInfo);
	
				TBase64 base64;
				User::LeaveIfError( base64.Decode( binaryCert, pck));	
				
				//create suject info for it
				CreateSubjectInfoL( info, certInfo);
					
				TDesC8& alias = subject2->AttributeValue()->Data()->Value();
				info->iAlias = alias.AllocL();

				RDEBUG8_3("PolicyEngineServer: Certificate mapped: %S -> %S", info->iCASN, info->iAlias);

				iCerts.AppendL( info);
				CleanupStack::Pop( info);
			
			}
			else
			{
				CleanupStack::PopAndDestroy( info);		
			}
			
			reserver2.Release();
			reserver1.Release();
			
		}
	}

	CleanupStack::PopAndDestroy( &attributes); //attribute list
	certReserver.Release();
	
	//Create pointer reference mapping instead of name mapping in certificate->certificate mapping table
	for ( TInt i(0); i < iCerts.Count(); i++)
	{
		//find all CSubjectInfos which include certificate to certificate mapping
		CSubjectInfo * infoi = iCerts[i];
		
		if ( infoi->iMappedToCert )
		{
			//find corresponding certificate
			for ( TInt j(0); j < iCerts.Count(); j++)
			{
				CSubjectInfo * infoj = iCerts[j];
				
				if ( *infoj->iCASN == *infoi->iMappedToCert)
				{
					//add reference mapping....
					RDEBUG("	-> added certificate reference mapping");
					infoi->iMappedToInfo = infoj;
					break;
				}
			}
		}
	}	
				
	//get roles mapping policy from storage
	CElementBase * rolesPolicy = iPolicyStorage->GetEditableElementL( RolesMappingPolicy);

	//if eleemnt is not valid
	if ( !rolesPolicy)
	{
		return;
	}
	
	//reserve and load element
	TElementReserver rolesReserver( rolesPolicy);
	iPolicyStorage->CheckElementL( rolesPolicy);

	//find roles for certificate, find policy subjects
	RElementArray roleattributes;	
	CleanupClosePushL( roleattributes);
	rolesPolicy->FindAttributesL( ESubject, roleattributes);

	for ( TInt i = 0; i < roleattributes.Count(); i++)
	{
		CElementBase * element = roleattributes[i];
		
		//only two subjectmatch allowed
		if ( element->ElementType() == ESubject && element->ElementCount() == 2 )
		{
			//element type should be subjectmatch in all cases!
			__ASSERT_ALWAYS ( element->Element(0)->ElementType() == ESubjectMatch, User::Panic(Panics::TrustedSessionManagerPanic, KErrCorrupt));
			__ASSERT_ALWAYS ( element->Element(1)->ElementType() == ESubjectMatch, User::Panic(Panics::TrustedSessionManagerPanic, KErrCorrupt));
		
			//get and reserve elements
			CMatchObject* subject1 = (CMatchObject*)element->Element(0);
			CMatchObject* subject2 = (CMatchObject*)element->Element(1);
			
			TElementReserver reserver1( subject1);
			TElementReserver reserver2( subject2);
			iPolicyStorage->CheckElementL( subject1);
			iPolicyStorage->CheckElementL( subject2);
				
			
			//check that reloes mapping is correct
			if ( subject1->AttributeDesignator()->GetAttributeid() == KTrustedSubject &&
			     subject2->AttributeDesignator()->GetAttributeid() == KRoleId )
			{
				//map roles to certificate
				AddRolesToCertL( subject2->AttributeValue()->Data()->Value(),
								 subject1->AttributeValue()->Data()->Value(), element->iElementState);
			}
			
			reserver2.Release();
			reserver1.Release();

		}
	}
	
	CleanupStack::PopAndDestroy( &roleattributes); //attribute list
	
	rolesReserver.Release();
}


void CCertificateMaps::BringUpToDateL()
{
	if ( !iMapsUpToDate)
	{
		LoadCertificateMapsL();
		iMapsUpToDate = ETrue;
	}
}


// -----------------------------------------------------------------------------
// CCertificateMaps::NewMappingsAvailable()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::NewMappingsAvailable()
{
	iMapsUpToDate = EFalse;
}
		

// -----------------------------------------------------------------------------
// CCertificateMaps::IsAliasExist()
// -----------------------------------------------------------------------------
//
TBool CCertificateMaps::IsAliasExistL( const TDesC8& aAlias)
{
	BringUpToDateL();

	//find subject info for aAlias (if info exist also alias exist)
	for ( TInt i = 0; i < iCerts.Count(); i++)
	{
		CSubjectInfo * info = iCerts[i];
		 
		//if alias match
		if ( info->iAlias)
		{
			if ( aAlias == *info->iAlias) 
				return ETrue;
		} 	
	}
	
	return EFalse;	
}


// -----------------------------------------------------------------------------
// CCertificateMaps::CertificateRoleL()
// -----------------------------------------------------------------------------
//
TRole CCertificateMaps::CertificateRoleL( const TCertInfo& aCertInfo, TBool aUseEditedItems)
	{
	RDEBUG("CCertificateMaps::CertificateRoleL()");
	BringUpToDateL();

	HBufC8* buf = CasnForCertInfoL( aCertInfo );
	TRole retVal = ENoRole;

	//find subject info for aAlias (if info exist also alias exist)
	RDEBUG_2("CCertificateMaps::CertificateRoleL() - checking %d certificates", iCerts.Count() );
	for( TInt i = 0; i < iCerts.Count(); i++)
		{
		// CSubjectInfo contains list of roles that are owned by the certificate
		CSubjectInfo* info = iCerts[ i ];
		
		//accept only elements which are committed...
		if( !EvaluateElementValidity( aUseEditedItems, info->iState ) )
			{
			RDEBUG("	-> found invalid element");
			continue;
			}
					 
		//if alias match
		if( info->iCASN->CompareF( *buf ) == 0 )
			{
			RDEBUG("	-> CASN comparison match");
			// recursive check if there is a mapping (e.g. cert_to_cert policy)
			retVal = info->CertificateRoleL( aUseEditedItems );
			if( retVal != ENoRole )
				{
				break;
				}
			}
		else
			{
			RDEBUG("	-> CASN did not match!");
			}
		}
	
	if( retVal == ECorporateRole )
		{
		RDEBUG("	-> found ECorporateRole");
		}
	else
		{
		RDEBUG("	-> no role found!");
		}

	delete buf;
	return retVal;	
	}



// -----------------------------------------------------------------------------
// CCertificateMaps::FindSubjectL()
// -----------------------------------------------------------------------------
//

CCertificateMaps::CSubjectInfo* CCertificateMaps::FindSubjectL( const TDesC8& aTrustedSubject, TBool aUseEditedItems)
{
	CSubjectInfo * info = NULL;
	
	BringUpToDateL();

	//find subject info for asubject
	for ( TInt i = 0; i < iCerts.Count(); i++)
	{
		info = iCerts[i];
		
		if ( !EvaluateElementValidity( aUseEditedItems, info->iState))
		{
			continue;
		}

		
		if ( info->Match( aTrustedSubject, EFalse))
		{
			return info;
		}
	}
	
	return NULL;
}


// -----------------------------------------------------------------------------
// CCertificateMaps::AddRolesToCertL()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::AddRolesToCertL( const TDesC8& aRole, const TDesC8& aSubject, TElementState aElementState)
	{
	RDEBUG("CCertificateMaps::AddRolesToCertL");
	RDEBUG("	-> ");
	
	for( TInt i = 0; i < iCerts.Count(); i++)
		{
		CSubjectInfo * info = iCerts[i];
		
		//if CASN match
		if( info->iCASN )
			{
			if( aSubject == *info->iCASN )
				{
				RDEBUG8_3("PolicyEngineServer: Role mapped: %S -> %S", &aSubject, &aRole );
				info->iRoles.AppendL( CRolesInfo::NewL( aRole, aElementState ) );
				break;
				}
			}
				
		//if alias match
		if( info->iAlias )
			{
			if ( aSubject == *info->iAlias)
				{
				RDEBUG8_3("PolicyEngineServer: Role mapped: %S -> %S", &aSubject, &aRole );
				info->iRoles.AppendL( CRolesInfo::NewL( aRole, aElementState ) );
				break;
				}
			} 		
		}
	}


HBufC8* CCertificateMaps::CasnForCertInfoL( const TCertInfo& aCertInfo)
{
	TInt certLength = aCertInfo.iIssuerDNInfo.iCountry.Length();
	certLength += aCertInfo.iIssuerDNInfo.iOrganizationUnit.Length();
	certLength += aCertInfo.iIssuerDNInfo.iOrganization.Length();
	certLength += aCertInfo.iIssuerDNInfo.iCommonName.Length();
	certLength += aCertInfo.iSerialNo.Length() * 2;
	certLength += aCertInfo.iFingerprint.Length() * 2;
	
	HBufC8* casn = HBufC8::NewL( certLength + 5 );
	TPtr8 ptr = casn->Des();
	
	if ( aCertInfo.iIssuerDNInfo.iCommonName.Length())
	{
		ptr.Append( aCertInfo.iIssuerDNInfo.iCommonName);
		ptr.Append( KCASNDelimeter);
	}
		
	if ( aCertInfo.iIssuerDNInfo.iOrganization.Length())
	{
		ptr.Append( aCertInfo.iIssuerDNInfo.iOrganization);
		ptr.Append( KCASNDelimeter);
	}

	if ( aCertInfo.iIssuerDNInfo.iOrganizationUnit.Length())
	{
		ptr.Append( aCertInfo.iIssuerDNInfo.iOrganizationUnit);
		ptr.Append( KCASNDelimeter);
	}
		
	if ( aCertInfo.iIssuerDNInfo.iCountry.Length())
	{
		ptr.Append( aCertInfo.iIssuerDNInfo.iCountry);
		ptr.Append( KCASNDelimeter);
	}

	if ( aCertInfo.iSerialNo.Length())
	{
		TInt serialLength = aCertInfo.iSerialNo.Length();
		TPtr8 serialNum( (unsigned char *)(ptr.Ptr() + ptr.Length()), serialLength * 2, serialLength * 2);
	
		//convert fingerprint to plain text
		for ( TInt i(0); i < aCertInfo.iSerialNo.Length(); i++)
		{
			ptr.AppendNumFixedWidth( aCertInfo.iSerialNo[i], EHex, 2);
		}	
			
		serialNum.UpperCase();
		ptr.Append( KCASNDelimeter);
	}

	if ( aCertInfo.iFingerprint.Length())
	{
		HBufC8* fingerPrint = HBufC8::NewLC( aCertInfo.iFingerprint.Length() * 2);
		TPtr8 fingerPrintPtr = fingerPrint->Des();
		CreateFingerPrint( fingerPrintPtr, aCertInfo);
		ptr.Append( fingerPrintPtr);
		CleanupStack::PopAndDestroy( fingerPrint);
	}


	return casn;
}


// -----------------------------------------------------------------------------
// CCertificateMaps::CreateFingerPrint()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::CreateFingerPrint( TDes8& aFingerPrint, const TCertInfo& aCertInfo)
{
	//convert fingerprint to plain text
	for ( TInt i(0); i < aCertInfo.iFingerprint.Length(); i++)
	{
			TBuf8<2> hexBuf;
			hexBuf.AppendNumFixedWidth( aCertInfo.iFingerprint[i], EHex, 2);
			hexBuf.UpperCase();
	
			aFingerPrint.Append(hexBuf);
	}	
}



// -----------------------------------------------------------------------------
// CCertificateMaps::CreateSubjectInfoL()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::CreateSubjectInfoL( CSubjectInfo * aInfo, const TCertInfo& aCertInfo)
{
	aInfo->iCASN = CasnForCertInfoL( aCertInfo);
	aInfo->iSubject = aCertInfo.iSubjectDNInfo.iCommonName.AllocL();
	
	aInfo->iFingerPrint = HBufC8::NewL(  aCertInfo.iFingerprint.Length() * 2);
	TPtr8 ptr = aInfo->iFingerPrint->Des();
	CreateFingerPrint( ptr, aCertInfo);
}



// -----------------------------------------------------------------------------
// CCertificateMaps::CreateSubjectInfoL()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::CreateSubjectInfoL( CSubjectInfo * aInfo, const TDesC8& aCertificate)
{
	//parse certificate
	CX509Certificate * cert = ParseCertificateL( aCertificate); 
	CleanupStack::PushL( cert);
				
	//parse subject info part (CASN, issued to)
	ParseSubjectInfoL( aInfo, cert);

	//destroy certificate				
	CleanupStack::PopAndDestroy( cert);
}

// -----------------------------------------------------------------------------
// CCertificateMaps::ParseCertificateL()
// -----------------------------------------------------------------------------
//
CX509Certificate* CCertificateMaps::ParseCertificateL( const TDesC8& aCertificate)
{
		RDEBUG("PolicyEngineServer: Certificate parsing");

		TPtrC8 certPtr = aCertificate;
		CX509Certificate* returnValue = 0;
				
		//if value contains CData marks it is binary coded, otherwise base64 coded
		if ( ParserUtility::ContainsCDataField( certPtr) )
		{
			RDEBUG("PolicyEngineServer: Binary format certificate detected, remove CDATA marks...");
			//remove cdata marks and create subject info
			ParserUtility::RemoveCDataMarksL( certPtr);
			RDEBUG_2("PolicyEngineServer: Binary format:", &aCertificate);

#ifdef _DEBUG	//
			TPtrC8 debugPtr = aCertificate;
			while ( debugPtr.Length())
			{
				TInt size = 100;
				if ( debugPtr.Length() < 100 ) size = debugPtr.Length();
				
				TPtrC8 temp = debugPtr.Left( size);
				debugPtr.Set( debugPtr.Mid( size));
				RDEBUG_2("%S", &temp);
			}
#endif	//#ifdef __DEBUG
			returnValue = CX509Certificate::NewL( certPtr);
		}
		else
		{
			RDEBUG("PolicyEngineServer: BASE64 format certificate detected, convert to binary format");
			RDEBUG("PolicyEngineServer: BASE64 format:");
#ifdef _DEBUG
			TPtrC8 debugPtr = aCertificate;
			while ( debugPtr.Length())
			{
				TInt size = 64;
				if ( debugPtr.Length() < 64 ) size = debugPtr.Length();
				
				TPtrC8 temp = debugPtr.Left( size);
				debugPtr.Set( debugPtr.Mid( size));
				RDEBUG_2("%S", &temp);
			}
#endif	//#ifdef __DEBUG
			//convert base64 coding to binary format
			TBase64 base64;
			
			HBufC8 * base64Cert = HBufC8::NewLC( certPtr.Length());
			TPtr8 base64Ptr = base64Cert->Des();
			User::LeaveIfError( base64.Decode( certPtr, base64Ptr));
					
			RDEBUG("PolicyEngineServer: Converting....");
			RDEBUG_2("PolicyEngineServer: Binary format (size %d bytes):", base64Ptr.Length());

#ifdef _DEBUG
			debugPtr.Set( base64Ptr);
			while ( debugPtr.Length())
			{
				TInt size = 100;
				if ( debugPtr.Length() < 100 ) size = debugPtr.Length();
				
				TPtrC8 temp = debugPtr.Left( size);
				debugPtr.Set( debugPtr.Mid( size));
				RDEBUG_2("%S", &temp);
			}
#endif	//#ifdef __DEBUG

			returnValue = CX509Certificate::NewL( base64Ptr);
			CleanupStack::PopAndDestroy( base64Cert);
		}


		RDEBUG("PolicyEngineServer: Certificate Ok!");
		return returnValue;
}


// -----------------------------------------------------------------------------
// CCertificateMaps::ParseSubjectInfo()
// -----------------------------------------------------------------------------
//

void CCertificateMaps::ParseSubjectInfoL( CSubjectInfo* aInfo, CX509Certificate* aCertificate)
{
	RDEBUG("PolicyEngineServer: CTrustedSession::ParseSubjectInfoL");


	//Parse distinguished name for subject (DN)
	aInfo->iSubject = ParseDNL( &aCertificate->SubjectName(), ETrue);
	RDEBUG8_2("PolicyEngineServer: Certificate subject: %S", aInfo->iSubject);

	//Parse issuer distinguished name(DN)
	HBufC8* ca = ParseDNL( &aCertificate->IssuerName(), EFalse);	
	
	//get serial number
	TBuf<64> serialNo;
	TPtrC8 serialPtr = aCertificate->SerialNumber();

	//convert serial no to plain text
	for ( TInt i(0); i < serialPtr.Length(); i++)
	{
		serialNo.AppendNumFixedWidth( serialPtr[i], EHex, 2);
	}
	
	serialNo.UpperCase();

	//get finger print
	TBuf8<40> fingerPrint;
	TPtrC8 fingerPtr = aCertificate->Fingerprint();
	
	//convert fingerprint to plain text
	for ( TInt i(0); i < fingerPtr.Length(); i++)
	{
		fingerPrint.AppendNumFixedWidth( fingerPtr[i], EHex, 2);
	}
	
	fingerPrint.UpperCase();
	aInfo->iFingerPrint = fingerPrint.AllocL();

	//joint issuer DN and Serial number (issuer DN + serial number + fingerprint + two delimeters= CASN) 
	ca = ca->ReAllocL( ca->Length() + serialNo.Length() + fingerPrint.Length() + 2);
	TPtr8 caPtr = ca->Des();
	caPtr.Append( serialNo);
	caPtr.Append( KCASNDelimeter);
	caPtr.Append( fingerPrint);
	
	aInfo->iCASN = ca;
	
	RDEBUG8_2("PolicyEngineServer: Certificate fingerprint: %S", aInfo->iFingerPrint);
	RDEBUG8_2("PolicyEngineServer: Certificate CASN: %S", ca);

}

// -----------------------------------------------------------------------------
// CCertificateMaps::ParseDNL()
// -----------------------------------------------------------------------------
//
	
HBufC8* CCertificateMaps::ParseDNL( const CX500DistinguishedName * aDN, TBool aOnlyCommonName)
{
	// DN country string
	TBuf8<4> country;
	// DN organisation unit
	TBuf8<64> organizationUnit;
	// DN orginasation
	TBuf8<64> organization;
	// DN common name
	TBuf8<64> commonName;
	// DN locality
	TBuf8<128> locality;	

	TDes8*	destination=NULL;
	TBool	found = EFalse;

	for ( TInt i(0); i < aDN->Count(); i++)
	{
		found = EFalse;
		const CX520AttributeTypeAndValue& attribute = aDN->Element(i);
	
		found = ETrue;
		if (!attribute.Type().Compare(KX520CountryName))
		{
			destination = &country;
		}
		else if(!attribute.Type().Compare(KX520OrganizationalUnitName))
		{
			destination = &organizationUnit;
		} 
		else if(!attribute.Type().Compare(KX520OrganizationName))
		{
			destination = &organization;
		}
		else if(!attribute.Type().Compare(KX520CommonName))
		{
			destination = &commonName;
		}
		else if(!attribute.Type().Compare(KX520LocalityName))
		{
			destination = &locality;
		}
		else
		{
			found = EFalse;
		}

		if ( found )
		{
			HBufC* value = attribute.ValueL();
			if ( value )
			{
				destination->Copy( *value);
			}
			
			delete value;
		}
	}
	
	HBufC8* retVal = NULL;
	
	if ( aOnlyCommonName)
	{
		//parse common name
		if ( commonName.Length())
		{
			retVal = commonName.AllocL();
		}
	}
	else
	{
		//create buffer for CA part
		TInt size = commonName.Length() + organization.Length() + organizationUnit.Length() + country.Length();
		retVal = HBufC8::NewL( size + 4);
		TPtr8 caPtr = retVal->Des();

		if ( commonName.Length())
		{
			caPtr.Append( commonName);
			caPtr.Append( KCASNDelimeter);
		}

		if ( organization.Length())
		{
			caPtr.Append( organization);
			caPtr.Append( KCASNDelimeter);
		}

		if ( organizationUnit.Length())
		{
			caPtr.Append( organizationUnit);
			caPtr.Append( KCASNDelimeter);
		}

		if ( country.Length())
		{
			caPtr.Append( country);
			caPtr.Append( KCASNDelimeter);
		}
	}
	
	return retVal;
}
	
	
// -----------------------------------------------------------------------------
// CCertificateMaps::ParseDNL()
// -----------------------------------------------------------------------------
//
TBool CCertificateMaps::EvaluateElementValidity( const TBool aUseEditedElements, const TElementState aState)
{
	if ( aUseEditedElements)
	{	
		//accept only elements which are committed...
		if ( aState == EDepricated || aState == EDeletedEditableElement)
		{
			return EFalse;
		}	
	}
	else
	{
		//ignore removed and depricated elements if not committed elements are in use
		if ( aState == EEditedElement ||  aState == EDeletedEditableElement || aState == EDepricated || aState == ENewElement)
		{
			return EFalse;
		}
	}	
	
	return ETrue;
}