networksecurity/ipsec/ipsec6/inc/sa_spec.h
changeset 0 af10295192d8
child 20 7e41d162e158
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/ipsec/ipsec6/inc/sa_spec.h	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,728 @@
+// Copyright (c) 2005-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:
+// sa_spec.h - IPv6/IPv4 IPSEC security associations
+// This file collects minimal definitions that need to be exported
+// from the Security Associations Database into Security Policy
+// database
+//
+
+
+
+/**
+ @internalComponent
+*/
+#ifndef __SA_SPEC_H__
+#define __SA_SPEC_H__
+
+#include <ip6_hook.h>
+#include "ipaddress.h"
+#include <networking/pfkeyv2.h>
+#include <networking/crypto.h>	// only for TAlgorithmClass, is this really necessary?
+#include "epdb.h"
+#include "ipseclog.h"
+
+// Selector applies to inbound packets
+const TUint KPolicyFilter_INBOUND = 0x1;
+// Selector applies to outbound packets
+const TUint KPolicyFilter_OUTBOUND = 0x2;
+// Selector applies to both inbound and outbound packets
+const TUint KPolicyFilter_SYMMETRIC =
+	KPolicyFilter_INBOUND|KPolicyFilter_OUTBOUND;
+
+// Indicate tunnel mode for Acquire and Verify (not really a filter).
+const TUint KPolicyFilter_TUNNEL = 0x4;
+
+// Selector can be merged with another matched selector.
+const TUint KPolicyFilter_MERGE = 0x8;
+
+// Negate selector -- drop if match occurs.
+const TUint KPolicyFilter_DROP = 0x10;
+// Final selector, do not look for "merge" selectors after this.
+const TUint KPolicyFilter_FINAL = 0x20;
+
+/**
+* Ports is present in selector.
+* The value indicates whether the content is actual port (1) or a packet
+* type/code (0) from ICMP, MH or other similar protocols.
+*/
+const TUint KTransportSelector_PORTS = 0x1;
+
+// Object tracking in the windows environment to
+// help detecting possible memory leaks.
+#if __WINS__ && _DEBUG
+	extern int IPSEC_OBJECT_COUNT;
+	#define	IPSEC_OBJECT_INC	++IPSEC_OBJECT_COUNT
+	#define	IPSEC_OBJECT_DEC	--IPSEC_OBJECT_COUNT
+	#define	IPSEC_OBJECT_TRACKING 1
+// ..when desperate, use the following ..
+//	#define	IPSEC_OBJECT_INC	do { Log::Printf(_L("INC[%u] %d"), (TInt)this, ++IPSEC_OBJECT_COUNT); } while (0)
+//	#define	IPSEC_OBJECT_DEC	do { Log::Printf(_L("DEC[%u] %d"), (TInt)this, --IPSEC_OBJECT_COUNT); } while (0)
+#else
+	#define	IPSEC_OBJECT_INC
+	#define	IPSEC_OBJECT_DEC
+	#undef	IPSEC_OBJECT_TRACKING
+#endif
+
+
+class CIpsecReferenceCountObject : public CBase
+	/**
+	* The base class for all IPSEC reference count objects.
+	*
+	* Many IPSEC objects are implemented as "reference counted objects"
+	* which automaticly delete self, when the last reference is removed.
+	*
+	* The contruction of the object is counted as one reference.
+	* The Open() and Close() methods are not supposed to be overridden,
+	* and are not defined "virtual". This base class attempts to be
+	* as light as possible
+	*
+	* The destructor is virtual and private. The reference counted
+	* objects are never deleted from outside, only from the Close()
+	* method.
+	*/
+	{
+public:
+#ifdef IPSEC_OBJECT_TRACKING
+	// Non-default constructor only needed for debugging
+	CIpsecReferenceCountObject() 
+		{
+		IPSEC_OBJECT_INC;
+		}
+#endif
+	inline void Open();
+	inline TInt IsShared() const;
+	void Close();
+protected:
+	virtual ~CIpsecReferenceCountObject()
+		{
+#ifdef IPSEC_OBJECT_TRACKING
+		// Non-empty destructor only needed for debugging
+		IPSEC_OBJECT_DEC;
+#endif
+		}
+	TInt iRefs;
+	};
+
+void CIpsecReferenceCountObject::Open()
+	/**
+	* Increment reference count.
+	*
+	* Records an additional reference to the object.
+	*/
+	{
+	++iRefs;
+	}
+
+TInt CIpsecReferenceCountObject::IsShared() const
+	/**
+	* Return the current reference count.
+	*
+	* The reference count works as implicit flag to
+	* test whether object has more than one reference
+	* to it (is shared).
+	*
+	* @li = 0, only one reference exist (not shared)
+	* @li > 0, other references exist (object is shared)
+	*
+	* @return The reference count
+	*/
+	{
+	return iRefs;
+	}
+
+class RPolicySelectorInfo
+	/**
+	* The policy selector information. This defines the IPSEC selector data layout,
+	* as is used as basic component in the transport selectors. This is also the
+	* basic information block, which is extracted from a packet (or flow).
+	*/
+	{
+public:
+	inline void FillZ();
+
+	TUint8 iFlags;				//< Transport Selector flags (KTransportSelector_*)				
+	TUint8 iProtocol;			//< IP Protocol code (0..255)
+	TUint8 iReserved1;			//< Reverved for future use.(now for alignment only)
+	TUint8 iReserved2;			//< Resevved for future use (now for alignment only)
+	//
+	TUint16 iPortRemote;		//< Remote port
+	TUint16 iPortLocal;			//< Local port
+	//
+	RIpAddress iRemote;			//< Remote Address with scope id
+	RIpAddress iLocal;			//< Local Address with scope id
+	};
+
+
+void RPolicySelectorInfo::FillZ()
+	// Fill all fields with ZERO (including possible compiler generated padding)
+	{
+	TUint32 *const p = (TUint32 *)this;
+	p[0] = p[1] = 0;	// iFlags, iProtocol, reserveds, iPortRemote, iPortLocal
+	}
+
+
+class TPolicyFilterInfo
+	/**
+	* The policy control and filter information.
+	*
+	* This defines the basic data for choosing the
+	* selectors which are tested for transport selectors.
+	* The filter can be based on
+	*
+	* - packet direction: inboud or outbound
+	* - interface index
+	*
+	* This includes some other action controlling
+	* flags, which affect the actions when the
+	* selector matches.
+	*
+	* - merge
+	* - final
+	* - drop
+	*
+	*/
+	{
+public:
+	TUint32 iFlags;		//< The KPolicyFilter_* flags.
+	TUint32 iIndex;		//< The Interface Index.
+	};
+
+class CTransportSelector : public CIpsecReferenceCountObject
+	/**
+	* The Transport Selector.
+	*
+	* A transport selector is a list of basic selectors or'ed together.
+	* The Transport Selector matches, if any of the basic selectors in
+	* the list match.
+	*
+	* The basic transport selector is a reference counted object. The contruction
+	* counts as the first reference and must be matched with corresponding
+	* Close(). Record additional references with Open().
+	*
+	* The contruction automaticly increments the next Or'ed selector. Once
+	* constructed, the selector is immutable. Aside from the reference count
+	* house keeping, the content of the selector is constant.
+	*/
+	{
+public:
+	CTransportSelector(const RPolicySelectorInfo &aData, const RPolicySelectorInfo &aMask, CTransportSelector *const aOr);
+	TInt Match(const RPolicySelectorInfo &aKey) const;
+private:
+	~CTransportSelector();
+	TInt iRefs;				 				//< The reference count.
+public:
+
+	// immutable after construction
+	const RPolicySelectorInfo iData;		//< The selector data (the values to check)
+	const RPolicySelectorInfo iMask;		//< The selector mask (what values to check)
+	CTransportSelector *const iOr;			//< Next alternative or NULL.
+	};
+
+//
+// Mapping of low level types in pfkeyv2.h into more semantic names
+// (This is to avoid a need to look many places in case pfkeyv2 changes)
+//
+typedef uint32_t TLifetimeAllocations;
+typedef uint64_t TLifetimeBytes;
+typedef uint64_t TLifetimeSeconds;
+
+
+/**
+// The default life time in seconds for larval SA's.
+// Larvar SA is created by GETSPI (may also be used as a default for
+// iLarvalLifetime in TSecurityAssocSpec).
+*/
+const TInt KLifetime_LARVAL_DEFAULT = 90;
+
+class CIdentity : public CIpsecReferenceCountObject
+	/**
+	* A container for the Identity string.
+	*/
+	{
+public:
+
+	// Create and construct a new Identity block
+	static CIdentity *NewL(const TDesC &aIdentity);
+	static CIdentity *NewL(const TDesC8 &aIdentity, TUint16 aType);
+	inline TUint16 Type() const	{return iType; }
+	inline TInt Match(const CIdentity &aOther) const;
+private:
+	// Construct and destruct are private, triggered internally.
+	CIdentity(TUint32 aLength) : iTypeLength(aLength) {};
+	~CIdentity() {}
+
+	TUint16 iType;						//< Type of the identity string (PREFIX, FQDN, USERFQDN)
+
+	// //
+	// *WARNING* *WARNING* *WARNING*
+	// What now follows, is the TLitC8 structure.
+	// The extra space is allocated only, if iTypeLength
+	// is non-zero.
+	// //
+	// Why this TLitC8 "hack" instead of traditional
+	// C construct with a "length" member and "fake buf[1]"?
+	//
+	// As far as layout, this is exactly the same. The TLitC8
+	// "hack" only forces a Symbian specific layout. When a
+	// descriptor is needed, it doesn't need to be constructed,
+	// it's already existing and just returning a reference
+	// to iTypeLength as TLitC8 is sufficient.
+	// //
+	const TUint iTypeLength;			//< TypeLength of TLitC8
+public:
+	inline const TDesC8 &Identity() const
+		/**
+		* Return the Identity string.
+		*
+		* @return The identity
+		*/
+		{
+		return ((TLitC8<1> &)iTypeLength)();
+		}
+	};
+	
+TInt CIdentity::Match(const CIdentity &aOther) const
+	/*
+	* Return ETrue, if identities match.
+	*
+	* @param aOther The other identity
+	* @return result of comparison.
+	*/
+	{
+	return Identity() == aOther.Identity();
+	}
+
+
+// TLifetime, a help structure
+
+class TLifetime
+	{
+public:
+	TLifetime(const struct sadb_lifetime &aLifetime);
+	static void Freeze(TTime &aTime, const TTime &aNow);
+	TLifetime();
+	// For current, these will count items used so far. For Hard and
+	// Soft these will contain the limit values for the current
+	// counts.
+	// study: present unspecified limit with 0 or max value?
+	TLifetimeAllocations iAllocations;	// Connections limit
+	TLifetimeBytes iBytes;				// Transmitted bytes limit
+	//
+	// For Current, these will record the creation and first use times.
+	// For Hard and Soft, these will record the expiration times (e.g.
+	// simple comparison with the current time can be used to test for
+	// expiration, and for returning CURRENT values to application, use
+	// the SecondsFrom method with current.
+	//
+	TTime iAddtime;						// Lifetime limit from creation
+	TTime iUsetime;						// Lifetime limit from first use
+	};
+
+
+class TSecurityAssocSpec
+	/**
+	* Security Association template.
+	*
+	* The TSecurityAssocSpec is a template for a Security Association.
+	* This information and the information extracted from the packet is used
+	* to locate a matching Security Association.
+	*/
+	{
+public:
+	TUint8 iType;				//< Security Association type (AH or ESP)
+	TUint8 iAalg;				//< Authentication algorithm number
+	TUint8 iEalg;				//< Encryption algorithm number
+	TUint8 iReplayWindowLength;	//< Use Replay Window
+	TUint iPfs:1;				//< "Perfect Forward Secresy" (PFS)
+
+	/**
+	* The SA is local address specicic.
+	*
+	* When set, the SA's is bound to a specific local
+	* address. If not set, the SA can be used with any of
+	* the currently valid own addresses.
+	*
+	* Note: The member name "iMatchSrc" is misleading.
+	*/
+	TUint iMatchSrc:1;
+
+	// MatchProxy retained for backward compatibility
+	TUint iMatchProxy:1;		//< (PFP) (deprecated) incoming == iMatchRemote, outgoing == iMatchLocal
+
+	// The PFP (Populate From Packet) flags
+	TUint iMatchLocal:1;		//< (PFP) Specific to local address of the packet
+	TUint iMatchRemote:1;		//< (PFP) Specific to remote address of the packet
+	TUint iMatchProtocol:1;		//< (PFP) Specific to protocol of the packet
+	TUint iMatchLocalPort:1;	//< (PFP) Specific to local port of the packet
+	TUint iMatchRemotePort:1;	//< (PFP) Specific to remtoe port of the packet
+
+	// Identity references
+	CIdentity *iIdentityLocal;	//< The local Identity
+	CIdentity *iIdentityRemote;	//< The remote Identity
+
+	// Limits for key lengths (for ACQUIRE only)
+	TUint16 iMinAuthBits, iMaxAuthBits;			//< Required length of the authentication key
+	TUint16 iMinEncryptBits, iMaxEncryptBits;	//< Required length of the encryption key
+
+	/**
+	* Max time for the Key Managers to handle ACQUIRE request.
+	*
+	* iLarvalLifetime specifies the maximum time to wait, after
+	* an ACQUIRE request originating from this template is sent
+	* to the key manager(s). This time should be long enough to
+	* allow key manager to complete the negotiation for an
+	* association.
+	*
+	* If not specified (=0), the default is #KLifetime_LARVAL_DEFAULT
+	*/
+	TUint iLarvalLifetime;
+
+	// Required lifetimes
+	struct sadb_lifetime iHard;	//< Hard Lifetime requirement (copied into ACQUIRE)
+	struct sadb_lifetime iSoft;	//< Soft Lifetime requirement (copied into ACQUIRE)
+	};
+
+class TAlgorithmMap
+	/**
+	* Map symbolic algorithm name with algorithm number.
+	*
+	* The symbolic name of the algorithm identifies the implementation. That is, the name
+	* given here is matched against the names advertised by the installed cryptograpchic
+	* libaries. Each installed cryptographic library provides a list of supported algorithm
+	* as names. This name is local concept.
+	*
+	* The algorithm number is the externally visible identification, which
+	* is used by the key management negotiations (in IKE etc), and appears in PFKEY messages.
+	*/
+	{
+public:
+	TAlgorithmMap(TAlgorithmClass aClass, TInt anId, TInt aBits, const TDesC &aLibrary, const TDesC &aAlgorithm);
+	TAlgorithmClass iClass;		//< Algorithm Class (digest, cipher, ...)
+	TInt iId;					//< IPsec algorithm id number
+	TInt iBits;					//< Actual # of bits to be used (digest only)
+
+	/**
+	* Name of the library instance.
+	* If iLibrary is empty,
+	* then the first matching algorithm from any of the
+	* installed libraries is used.
+	*/
+	TProtocolName iLibrary;
+	/**
+	* Name of the algorithm.
+	* If iAlgorithm is empty, then
+	* this map entry describes a NULL algorithm. No libraries
+	* are searched.
+	*/
+	TAlgorithmName iAlgorithm;
+	};
+
+class CAlgorithmList : public CArrayFixFlat<TAlgorithmMap>
+	/**
+	* List of potentially available algorithtms.
+	*
+	* CAlgorithmList is an array of TAlgorithmMap entries and provides methods
+	* for finding a specific map and adding new mapping. The use of this information
+	* is documented in more detail in connection of the Cryptographic library.
+	*
+	* The algorithm list defines all potentially available algorithms. The actual
+	* set of available algorithms depends on currently installed crypto libraries.
+	*/
+	{
+public:
+	CAlgorithmList();
+	void AddL(TAlgorithmClass aClass, TInt anId, TInt aBits, const TDesC &aLibrary, const TDesC &anAlg);
+	TAlgorithmMap *Lookup(TAlgorithmClass aClass, TInt anAlg) const;
+	TAlgorithmMap *Lookup(const TDesC &aLibrary, const TDesC &anAlg) const;
+	};
+
+
+
+class CSecurityAssoc;
+class REndPoints;
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+class CPropList;
+#endif //SYMBIAN_IPSEC_VOIP_SUPPORT
+
+
+class MAssociationManager
+	/**
+	* The Security Association Database (SDB) interface as seen by Security Policy.
+	*/
+	{
+public:
+	virtual void Open() = 0;
+	virtual void Close() = 0;
+
+	/**
+	* Acquire a new Security Association.
+	*
+	* SECPOL calls this when it needs a Security Association for a flow.
+	*
+	* If a matching Security Association already exists, it is returned.
+	* Otherwise this generates a PFKEY ACQUIRE message for each registered
+	* key management application and the function returns without SA.
+	*
+	* When not found, this creates a "larval egg SA" that will match any
+	* future request with same parameters. This prevents generating multiple
+	* ACQUIRE messages for the same security association.
+	*
+	* @retval aSa	located SA
+	* @param aSpec	SA requirements
+	* @param aPropList The list of (possibly multiple) proposals pertaining to the aSa
+	* @param aTS	The traffic selector.
+	* @param aSrc	the source address (of SA)
+	* @param aDst	the destination address (of SA)
+	* @param aInfo	the selector information
+	* @param aTunnel True, when association is used in tunnel mode.
+	* @returns
+	* @li	KErrNone        SA found and returned.
+	* @li	KRequestPending SA found (or created), but in LARVAL state
+	* @li	KErrDied        the new larval SA expired (some weird problem)
+	* @li	KErrNotFound    creating SA failed (parameters error? memory?)
+	*/
+	virtual TInt Acquire(
+		CSecurityAssoc * &aSa,
+		const TSecurityAssocSpec &aSpec,
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+		const CPropList *aPropList,
+#endif //SYMBIAN_IPSEC_VOIP_SUPPORT
+		const CTransportSelector *aTS,
+		const RIpAddress &aSrc,
+		const RIpAddress &aDst,
+		const RPolicySelectorInfo &aInfo,
+		TBool aTunnel) = 0;
+
+	/**
+	* Verify Security Association.
+	*
+	* SECPOL calls this to verify that the applied SA matches the
+	* policy specification.
+	*
+	* @param aSa	the SA to be verified
+	* @param aSpec	the required SA features
+	* @param aSrc	the source address from the packet
+	* @param aDst	the destination address of the packet
+	* @param aInfo	the selector information
+	*
+	* @returns
+	*	@li	KErrNone, when all is OK
+	*	@li	error < 0, when something doesn't match
+	*/
+	virtual TInt Verify(
+		const CSecurityAssoc *aSa,
+		const TSecurityAssocSpec &aSpec,
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+		const CPropList *aPropList,
+#endif // SYMBIAN_IPSEC_VOIP_SUPPORT	
+		const RIpAddress &aSrc,
+		const RIpAddress &aDst,
+		const RPolicySelectorInfo &aInfo) = 0;
+		
+	
+	/**
+	* Outgoing packet transformation for IPSEC
+	*
+	* SECPOL calls this once for each packet for each IPsec required
+	* IPsec transform (ESP or AH).
+	*
+	* First, applies the tunnel transform, if present.
+	* After this, applies the IPSEC transform specified by the Security
+	* Association if present.
+	* Having a NULL SA parameter allows this to be used as a plain
+	* tunnel wrapper.
+	*
+	* @param aSa		The SA to be applied to the packet (or NULL)
+	* @param aPacket	The outgoing packet
+	* @param aInfo		The info block associated with the packet
+	* @param aTunnel	The outer tunnel destination (request tunneling if specified)
+	*
+	* @returns
+	* @li KErrNone, if transformation successfully done
+	* @li KErrGeneral, otherwise (some error condition occurred)
+	*/
+	virtual TInt ApplyL(
+		CSecurityAssoc* aSa,
+		RMBufSendPacket &aPacket,
+		RMBufSendInfo &aInfo,
+		const TIpAddress &aTunnel) = 0;
+
+	/**
+	* Incoming packet transformation for IPSEC (one layer).
+	*
+	* SECPOL calls this for each incoming packet when the next
+	* procotol indicates IPsec header (AH or ESP).
+	*
+	* Decode IPSEC layer from the received packet and return the
+	* the applied Security Association and the optional tunnel
+	* address.
+	*
+	* @retval aSa		Returns the SA that was used by this transformation (if any)
+	* @param aPacket	The incoming packet
+	* @param aInfo		The info block associated with the packet
+	* @param aProtocol	The protocol (either AH or ESP, and maybe UDP for NAT traversal)
+	* @retval aTunnel	Returns outer source address, if detunneling was done. Otherwise
+	*					just unspecified address.
+	* @returns
+	* @li	< 0, transform failed with error
+	* @li	>= 0, transform succesfull, the next protocol id after unwrap.
+	*
+	* @exception leave	transform failed with an error
+	*
+	* If the input aProtocol is not ESP, AH or IP-in-IP, this function does
+	* nothing and just returns the aProtocol and packet unchanged!!
+	*/
+	virtual TInt ApplyL(
+		CSecurityAssoc* &aSa,
+		RMBufRecvPacket &aPacket,
+		RMBufRecvInfo &aInfo,
+		TInt aProtocol,
+		TIpAddress &aTunnel) = 0;
+
+	/**
+	* Returns the maximum overhead caused by this SA/Tunnel combination
+	* for an outbound packet.
+	*
+	* @param aSa		the association (can be null)
+	* @param aTunnel	request IPSEC tunneling, if address is specified
+	*
+	* @return	the header overhead caused by the transformation
+	*/
+	virtual TInt Overhead(const CSecurityAssoc *const aSa, const TIpAddress &aTunnel) const = 0;
+
+	/**
+	* Unconditionally remove all references to the SA and destroy the object,
+	*
+	* The Security Association must be deleted by this function, the ~CSecurityAssociation()
+	* destructor must not be invoked from outside this function.
+	*
+	* Remove the association from the hash table (iHash) and terminate
+	* the pending timer (if any).
+	*
+	* @param aSa	The SA (NULL also allowed for NOP)
+	*/
+	virtual void Delete(CSecurityAssoc *aSa) = 0;
+
+	/**
+	* Activate a timeout callback for SA.
+	*
+	* CSecurityAssociation calls this to set a timer for self when the SA
+	* has time based lifetime. Unless cancelled, timeout expiration calls the
+	* CSecurityAssoc::TimerExpired after aDelta seconds has passed.
+	*
+	* @param aSa The affected SA
+	* @param aDelta The timeout
+	*/
+	virtual void TimerOn(CSecurityAssoc &aSa, TInt aDelta) = 0;
+
+	/**
+	* Generate Expired message.
+	* Called by CSecurityAssocition, when it detects that lifetime has expired (hard)
+	* or is about to expired (soft). Generate an Expired message and deliver it to all
+	* interested parties.
+	*
+	* @param aSa	The association
+	* @param aType	Expiration type (SADB_EXT_LIFETIME_SOFT, SADB_EXT_LIFETIME_HARD)
+	* @param aLifetime Expired lifetime
+	*/
+	virtual void Expired(const CSecurityAssoc &aSa, TInt aType, const TLifetime &aLifetime) = 0;
+
+	/**
+	* Deliver Algorithm map from policy to Security Association Database (SAD).
+	*
+	* If successful, the SAD takes ownership of the table and sets aList to NULL.
+	* If not succesful, the ownership of the table remains
+	* with the caller (aList is not changed).
+	*
+	* @param aList	The algorithm List.
+	*/
+	virtual void SetAlgorithms(CAlgorithmList*& aList) = 0;
+
+	/**
+	* Find an SA matching the parameters.
+	*
+	* If SA cannot be located with the given destination address, the search
+	* is repeated with no destination address.
+	*
+	* This function exists ONLY for locating the INCOMING SA for a packet,
+	* which has AH or ESP header..
+	*
+	* @param aType		the Association Type (AH or ESP)
+	* @param aSPI		the SPI number
+	* @param aDst		the destination address (never NONE)
+	* @returns
+	* @li non NULL,   pointer to CSecurityAssociation, if found
+	* @li NULL,       if the requested association does not exist
+	*/
+	virtual CSecurityAssoc *Lookup(TUint8 aType, TUint32 aSPI, const TIpAddress &aDst) const = 0;
+
+	/**
+	* Return the named EndPoint collection.
+	*
+	* Security Associtiations can be bound to named end points. The same EP's can be
+	* referenced in the security policy. To allow this, the Security Policy (SPD) and
+	* Security Association Databases (SAD) must use a shared "name space" for the
+	* end points.
+	*
+	* The end point collection is owned by SAD, and the SPD needs to find a reference
+	* to the same instance using this function.
+	*
+	* @return The end point collection.
+	*/
+	virtual REndPoints &EndPointCollection() = 0;
+	};
+
+
+class RSecurityAssociation;
+
+/**
+* Security Association callback.
+*/
+typedef void (*SecurityAssociationCallback)(RSecurityAssociation &aAssoc);
+
+class RSecurityAssociation : public RCircularList
+	/**
+	* Security Association handle.
+	*
+	* The handle contains a reference to a security association. The circular
+	* list links together handles, which reference the same association. The
+	* "head" of the list is in the security association.
+	*
+	* The callback function is called when the state of the association changes
+	* in any way.
+	*/
+	{
+	friend class CSecurityAssoc;
+	friend class CProtocolKey;
+public:
+
+	TInt Status() const;
+	void Init(SecurityAssociationCallback aCallback);
+	void None();
+	void Reset(CSecurityAssoc *aSa);
+
+	inline CSecurityAssoc *Association() const
+		{
+		return iAssociation;
+		}
+	inline TInt ReadErr()const { return iErrorVal; }
+	inline void SetError(TInt aError) { iErrorVal=aError; }
+private:
+	CSecurityAssoc *iAssociation;			//< The security association.
+	SecurityAssociationCallback iCallback;	//< The callback function.
+	TInt iErrorVal;				            // Stores the error value returned by KMD server
+	};
+
+
+#endif