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